{"id":51300727,"url":"https://github.com/kevinvandy/tanstack-table-benchmarks","last_synced_at":"2026-06-30T19:02:11.954Z","repository":{"id":368079507,"uuid":"1276941435","full_name":"KevinVandy/tanstack-table-benchmarks","owner":"KevinVandy","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-28T23:49:21.000Z","size":131,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-29T01:19:38.057Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KevinVandy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-22T12:40:50.000Z","updated_at":"2026-06-28T23:49:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/KevinVandy/tanstack-table-benchmarks","commit_stats":null,"previous_names":["kevinvandy/tanstack-table-benchmarks"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/KevinVandy/tanstack-table-benchmarks","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVandy%2Ftanstack-table-benchmarks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVandy%2Ftanstack-table-benchmarks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVandy%2Ftanstack-table-benchmarks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVandy%2Ftanstack-table-benchmarks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KevinVandy","download_url":"https://codeload.github.com/KevinVandy/tanstack-table-benchmarks/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinVandy%2Ftanstack-table-benchmarks/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34979578,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-30T19:02:11.175Z","updated_at":"2026-06-30T19:02:11.942Z","avatar_url":"https://github.com/KevinVandy.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TanStack Table Benchmark Examples\n\nDedicated memory and row-model operation benchmarks for similar TanStack Table v8 and v9 React examples.\n\nEach benchmark is an independent Vite example with its own `package.json`, mirroring the structure of the existing TanStack examples:\n\n- `examples/v8/virtualized-rows`\n- `examples/v8/virtualized-columns`\n- `examples/v8/paginated-rows`\n- `examples/v8/kitchen-sink`\n- `examples/v8/sorting-fns`\n- `examples/v8/filtering-fns`\n- `examples/v8/aggregation-fns`\n- `examples/v9/virtualized-rows`\n- `examples/v9/virtualized-columns`\n- `examples/v9/paginated-rows`\n- `examples/v9/kitchen-sink`\n- `examples/v9/sorting-fns`\n- `examples/v9/filtering-fns`\n- `examples/v9/aggregation-fns`\n\nShared deterministic data, config parsing, and CSS live in `shared/src`.\n\n## Install\n\n```sh\npnpm install\n```\n\n## v9 Version Maintenance\n\nKeep the tracked `examples/v9/*` examples on the latest published v9 beta before using them as the baseline for PR comparisons. Update every v9 example that depends on `@tanstack/react-table` and/or `@tanstack/table-core`, then refresh only the tracked v9 workspace importers in the lockfile:\n\n```sh\nVERSION=9.0.0-beta.21\n\nfor d in examples/v9/*; do\n  if [ -f \"$d/package.json\" ]; then\n    node -e \"const p=require('./$d/package.json'); process.exit(p.dependencies?.['@tanstack/react-table'] ? 0 : 1)\" \u0026\u0026\n      (cd \"$d\" \u0026\u0026 npm pkg set \"dependencies.@tanstack/react-table=$VERSION\")\n    node -e \"const p=require('./$d/package.json'); process.exit(p.dependencies?.['@tanstack/table-core'] ? 0 : 1)\" \u0026\u0026\n      (cd \"$d\" \u0026\u0026 npm pkg set \"dependencies.@tanstack/table-core=$VERSION\")\n  fi\ndone\n\npnpm install --lockfile-only --filter './examples/v9/**'\n```\n\n## PR Preview Setup\n\nTo compare a table PR against the current v9 baseline, copy the tracked v9 examples to a temporary folder and install the PR preview packages into the copy. Use a unique package name for each copied example so pnpm workspace discovery does not see duplicate package names:\n\n```sh\nPR=6347\nTEMP=\"examples/v9-pr-temp-$PR\"\n\ncp -R examples/v9 \"$TEMP\"\n\nfor d in \"$TEMP\"/*; do\n  if [ -f \"$d/package.json\" ]; then\n    name=\"benchmark-table-v9-pr-$PR-$(basename \"$d\")\"\n    (cd \"$d\" \u0026\u0026 npm pkg set \"name=$name\")\n    (cd \"$d\" \u0026\u0026 npm install --force --prefer-online \\\n      \"https://pkg.pr.new/TanStack/table/@tanstack/table-core@$PR\" \\\n      \"https://pkg.pr.new/TanStack/table/@tanstack/react-table@$PR\")\n  fi\ndone\n```\n\nThese `v9-pr-temp-*` folders are intended as local benchmark fixtures. Do not treat their generated package locks, builds, or result files as part of the normal tracked benchmark baseline unless a specific comparison needs to be preserved.\n\n## Run\n\n```sh\npnpm bench:memory\n```\n\nUseful flags:\n\n```sh\npnpm bench:memory -- --iterations 5 --overscan 5\n```\n\nRun only one benchmark group:\n\n```sh\npnpm bench:memory -- --benchmark rows\npnpm bench:memory -- --benchmark columns\npnpm bench:memory -- --benchmark paginated-rows\npnpm bench:memory -- --benchmark kitchen-sink\n```\n\nCapture beginning/end heap snapshots for the first iteration of each v8/v9/config combination:\n\n```sh\npnpm bench:memory -- --heapSnapshots true\n```\n\nBy default snapshots are captured only for configs with at most `10,000` estimated cells, because large browser heap snapshots can be multiple GB and impractical to create or parse locally. Adjust with:\n\n```sh\npnpm bench:memory -- --heapSnapshots true --maxSnapshotCells 100000\n```\n\nSmooth scroll phases are captured only for configs with at most `1,000,000` estimated cells by default. Larger configs still record initial and instant-scroll phases, plus a `smooth-scroll-skipped` marker. Adjust with:\n\n```sh\npnpm bench:memory -- --maxSmoothScrollCells 10000000\n```\n\nThe runner builds each independent example, starts `vite preview` for one example at a time, opens it in a fresh Chromium context, and records:\n\n- `JSHeapUsedSize` before forced GC\n- `JSHeapUsedSize` after forced GC\n- memory reclaimed by forced GC\n- DOM document, node, and event listener counts\n- rendered row and cell counts for equivalence checks\n\nIt measures these phases:\n\nVirtualized examples:\n\n- `initial`\n- `instant-middle-scroll`\n- `instant-end-scroll`\n- `smooth-middle-scroll`\n- `smooth-end-scroll`\n\nPaginated examples:\n\n- `initial`\n- `next-page`\n- `last-page`\n\nResults are written to `results/*.json`, `results/*.csv`, and `results/*.html`.\n\n## Operation Performance Benchmarks\n\nRun sorting, filtering, and aggregation row-model benchmarks:\n\n```sh\npnpm bench:performance\n```\n\nUseful flags:\n\n```sh\npnpm bench:performance -- --iterations 3 --warmups 0\npnpm bench:performance -- --operation sorting\npnpm bench:performance -- --operation filtering --scenario includesString\npnpm bench:performance -- --operation aggregation --scenario sum\npnpm bench:performance -- --rows 30000,300000\npnpm bench:performance -- --includeV9Only false\npnpm bench:performance -- --pipeline full\n```\n\nThe operation runner builds the matching v8 and v9 operation examples, starts `vite preview` for one example at a time, opens the app in Chromium, and calls a headless browser benchmark API exposed by the example. Sorting, filtering, and aggregation live in separate example directories so a targeted run only builds and launches the relevant pair. Each sample creates a fresh table instance and times the first `table.getRowModel()` call for that scenario. By default, `--pipeline operation` primes the core row model before timing so the measurement is closer to an interactive sort/filter/group action on an existing table. Use `--pipeline full` to include core row construction in the timed section.\n\nThe default row-count matrix is `30,000` and `300,000` rows. The performance runner ignores row counts above `300,000` to keep memory pressure from dominating the measurements. Smaller row counts are useful for smoke tests, but sub-millisecond operation timings can produce noisy percentages.\n\nOperation benchmark data is generated once from seeded Faker data into `shared/generated/perfData.json` before the runner builds examples. The fixture is ignored by git and regenerated only when the requested capped row count does not match the existing fixture. Both v8 and v9 examples load the same prebuilt JSON fixture once before reporting benchmark readiness, and each sample reuses cached slices from that array.\n\nGenerate the standalone fixture manually before running an operation example directly:\n\n```sh\npnpm generate:performance-data -- --rows 300000\n```\n\nLong runs print progress for fixture generation, example builds, preview server startup, each version, and each operation/row-count group.\n\nFor aggregation scenarios, the benchmark reads grouped aggregate values inside the timed section so the aggregation functions are actually executed.\n\nOperation benchmark results are written to `results/performance-*.json`, `results/performance-*.csv`, and `results/performance-*.html`.\n\n## Notes\n\nThe examples intentionally use the same React, React DOM, TanStack Virtual, Vite, and deterministic data generator. The main intended variable is `@tanstack/react-table` v8 versus v9.\n\nDefault sample size is `5` iterations.\n\nDefault dimensions:\n\nRows benchmark:\n\n- `10` rows x `8` columns\n- `1,000` rows x `8` columns\n- `100,000` rows x `8` columns\n- `1,000,000` rows x `8` columns\n\nPaginated rows benchmark:\n\n- `10` rows x `8` columns\n- `1,000` rows x `8` columns\n- `100,000` rows x `8` columns\n- `1,000,000` rows x `8` columns\n\nKitchen sink benchmark:\n\n- `10` rows x `8` columns\n- `1,000` rows x `8` columns\n- `100,000` rows x `8` columns\n- `1,000,000` rows x `8` columns\n\nColumns benchmark:\n\n- `10` rows x `10` columns\n- `100` rows x `100` columns\n- `100` rows x `1,000` columns\n- `100` rows x `10,000` columns\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinvandy%2Ftanstack-table-benchmarks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinvandy%2Ftanstack-table-benchmarks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinvandy%2Ftanstack-table-benchmarks/lists"}