Skip to content

feat: update to table v9 and redesign table landing page - #1102

Open
KevinVandy wants to merge 3 commits into
mainfrom
table-v9-landing-page
Open

feat: update to table v9 and redesign table landing page#1102
KevinVandy wants to merge 3 commits into
mainfrom
table-v9-landing-page

Conversation

@KevinVandy

@KevinVandy KevinVandy commented Aug 3, 2026

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Added an updated TanStack Table v9 preview with filtering, sorting, pagination, column visibility, row and cell selection, keyboard navigation, and range selection.
    • Expanded examples and guidance covering reactive state, extensibility, reusable hooks, and Devtools.
    • Added framework information for Lit, Alpine, and Vanilla.
  • Improvements

    • Updated table descriptions, feature highlights, version information, and framework expertise.
    • Preserved existing admin table functionality through compatibility support.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

TanStack Table is pinned to V9 beta. The landing workbench and example use V9 feature plugins and useTable. Admin routes use the legacy adapter. Table catalog metadata now describes V9 and its supported frameworks.

Changes

TanStack Table V9 adoption

Layer / File(s) Summary
V9 dependency and legacy admin compatibility
package.json, src/routes/admin/*
The project pins @tanstack/react-table to V9 beta. Admin tables use legacy hooks and types while retaining existing row-model and rendering APIs.
V9 landing workbench implementation
src/components/landing/TableLanding.tsx, src/components/landing/codeExamples.ts
The workbench and example register V9 features, use useTable, render with table.FlexRender, and add reactive state, sorting, filtering, pagination, visibility, row selection, and cell selection interactions.
V9 concepts and tooling presentation
src/components/landing/TableLanding.tsx
The landing page presents state ownership, row-model stages, performance behavior, reusable hooks, custom features, and Devtools.
Table metadata refresh
src/libraries/libraries.ts, src/libraries/maintainers.ts, src/libraries/table.tsx
The Table catalog metadata now describes V9, adds framework entries and expertise, updates versions, and replaces the feature highlights and icon.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: tannerlinsley

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant TableWorkbench
  participant useTable
  participant table.state
  participant table.FlexRender
  User->>TableWorkbench: Select or navigate cells
  TableWorkbench->>useTable: Update registered feature state
  useTable->>table.state: Read selection and pagination state
  TableWorkbench->>table.FlexRender: Render headers and cells
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: updating to Table v9 and redesigning the table landing page.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch table-v9-landing-page

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 3, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tanstack-com ed1d9ab Commit Preview URL

Branch Preview URL
Aug 03 2026, 04:00 PM

@socket-security

socket-security Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​tanstack/​react-table@​8.21.3 ⏵ 9.0.0-beta.78100100100 +2898 +1100

View full report

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/routes/admin/roles.index.tsx (2)

1-1: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Missing lint-suppression comment on two of six migrated admin tables.

Four admin route files (audit.tsx, github-stats.tsx, logins.tsx, roles.$roleId.tsx) precede their useReactTable call with // eslint-disable-next-line react-hooks/incompatible-library because the aliased useLegacyTable as useReactTable hook shape trips this lint rule. Two files migrated to the same hook shape but did not carry over the comment:

  • src/routes/admin/roles.index.tsx#L386-391: add // eslint-disable-next-line react-hooks/incompatible-library immediately above the const table = useReactTable({ call at line 387.
  • src/routes/admin/users.tsx#L752-762: add // eslint-disable-next-line react-hooks/incompatible-library immediately above the const table = useReactTable({ call at line 757.

If lint is enforced in CI, both call sites are likely to fail lint the same way the other four files would without the comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/admin/roles.index.tsx` at line 1, Add the eslint-disable-next-line
react-hooks/incompatible-library comment immediately above each const table =
useReactTable({ call in the roles index and users admin route components,
matching the suppression already used by the other migrated admin tables.

386-391: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add the missing lint-suppression comment for the legacy table hook.

Every other admin route that calls the aliased useLegacyTable as useReactTable hook (audit.tsx, github-stats.tsx, logins.tsx, roles.$roleId.tsx) precedes the call with // eslint-disable-next-line react-hooks/incompatible-library. This file omits it before the useReactTable call at line 387. If the rule fires on this hook shape elsewhere, it will likely also fire here and can fail lint in CI.

See the consolidated comment for the shared fix across this file and src/routes/admin/users.tsx.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/admin/roles.index.tsx` around lines 386 - 391, Add the
eslint-disable-next-line react-hooks/incompatible-library suppression
immediately before the useReactTable call that creates the table instance in the
roles route, matching the existing legacy-table hook usage in the other admin
routes.
src/routes/admin/users.tsx (1)

752-762: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add the missing lint-suppression comment for the legacy table hook.

This file's useReactTable call at line 757 lacks the // eslint-disable-next-line react-hooks/incompatible-library comment that precedes the same call shape in every other admin route file. See the consolidated comment for the shared fix across this file and src/routes/admin/roles.index.tsx.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/routes/admin/users.tsx` around lines 752 - 762, Add the `//
eslint-disable-next-line react-hooks/incompatible-library` suppression
immediately before the `useReactTable` call in the relevant admin users route,
matching the existing pattern used by other admin routes. Do not alter the table
configuration or pagination logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/landing/TableLanding.tsx`:
- Around line 391-424: Add a focusable tabIndex to the gridRef container used as
the useHotkeys target, ensuring the grid can receive keyboard events before any
cell is clicked while preserving the existing cell-level tabIndex behavior.

In `@src/libraries/libraries.ts`:
- Around line 313-315: Update the table metadata around latestVersion,
latestBranch, and availableVersions only after verifying that the TanStack Table
v9 documentation branch exists; use the resolved branch configuration to ensure
latest and explicit versions validate correctly, and rename or remove beta so
/table/beta cannot serve unintended content.

In `@src/libraries/table.tsx`:
- Around line 69-82: Update the “Reactive by Design” description to qualify the
fine-grained rendering claim: state that unrelated table parts avoid
re-rendering when narrow selectors or isolated subscriptions are used, rather
than presenting it as the default behavior of TanStack Table React hooks. Keep
the surrounding reactivity explanation unchanged.

---

Outside diff comments:
In `@src/routes/admin/roles.index.tsx`:
- Line 1: Add the eslint-disable-next-line react-hooks/incompatible-library
comment immediately above each const table = useReactTable({ call in the roles
index and users admin route components, matching the suppression already used by
the other migrated admin tables.
- Around line 386-391: Add the eslint-disable-next-line
react-hooks/incompatible-library suppression immediately before the
useReactTable call that creates the table instance in the roles route, matching
the existing legacy-table hook usage in the other admin routes.

In `@src/routes/admin/users.tsx`:
- Around line 752-762: Add the `// eslint-disable-next-line
react-hooks/incompatible-library` suppression immediately before the
`useReactTable` call in the relevant admin users route, matching the existing
pattern used by other admin routes. Do not alter the table configuration or
pagination logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 09d163dc-fbfd-46cd-99ea-e700774d2a6c

📥 Commits

Reviewing files that changed from the base of the PR and between a013ad9 and 1ec979d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • package.json
  • src/components/landing/TableLanding.tsx
  • src/components/landing/codeExamples.ts
  • src/libraries/libraries.ts
  • src/libraries/maintainers.ts
  • src/libraries/table.tsx
  • src/routes/admin/audit.tsx
  • src/routes/admin/github-stats.tsx
  • src/routes/admin/logins.tsx
  • src/routes/admin/roles.$roleId.tsx
  • src/routes/admin/roles.index.tsx
  • src/routes/admin/users.tsx

Comment on lines +391 to +424
useHotkeys(
[
{ hotkey: 'ArrowUp', callback: () => table.moveCellSelection('up') },
{ hotkey: 'ArrowDown', callback: () => table.moveCellSelection('down') },
{ hotkey: 'ArrowLeft', callback: () => table.moveCellSelection('left') },
{
hotkey: 'ArrowRight',
callback: () => table.moveCellSelection('right'),
},
{
hotkey: 'Shift+ArrowUp',
callback: () => table.extendCellSelection('up'),
},
{
hotkey: 'Shift+ArrowDown',
callback: () => table.extendCellSelection('down'),
},
{
hotkey: 'Shift+ArrowLeft',
callback: () => table.extendCellSelection('left'),
},
{
hotkey: 'Shift+ArrowRight',
callback: () => table.extendCellSelection('right'),
},
{ hotkey: 'Mod+A', callback: () => table.selectAllCells() },
{ hotkey: 'Escape', callback: () => table.resetCellSelection(true) },
],
{ preventDefault: true, target: gridRef },
)

const filteredRows = table.getFilteredRowModel().rows.length
const selectedRows = table.getSelectedRowModel().rows.length
const selectedCells = table.getSelectedCellCount()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add tabIndex to the cell-navigation target so hotkeys work before the first click.

useHotkeys scopes arrow-key, Shift+arrow, Mod+A, and Escape handling to target: gridRef (line 419). The TanStack Hotkeys documentation states: "Set tabIndex on elements used as target refs so they can receive keyboard events." The gridRef container (lines 509-514) has no tabIndex.

Individual <td> cells do get tabIndex through cell.getTabIndex(), so keydown events bubble to the target once a cell has been focused by mouse. Before any cell is focused (for example, right after the page loads), nothing inside gridRef has focus, so the arrow-key and Mod+A/Escape hotkeys will not fire until the user first clicks a cell.

⌨️ Proposed fix to make the grid focusable
         <div
           ref={gridRef}
           aria-label="Issue table with selectable cells"
           className="mt-3 overflow-x-auto rounded-lg border border-border-subtle"
           role="region"
+          tabIndex={0}
         >
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/landing/TableLanding.tsx` around lines 391 - 424, Add a
focusable tabIndex to the gridRef container used as the useHotkeys target,
ensuring the grid can receive keyboard events before any cell is clicked while
preserving the existing cell-level tabIndex behavior.

Comment on lines +313 to +315
latestVersion: 'v9',
latestBranch: 'main',
availableVersions: ['v8', 'beta'],
availableVersions: ['v9', 'v8', 'beta'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n --glob '*.ts' --glob '*.tsx' \
  'latestVersion|availableVersions|/table/(latest|v9|beta|v8)' .

Repository: TanStack/tanstack.com

Length of output: 9583


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== libraries.ts table library excerpt =="
sed -n '280,340p' src/libraries/libraries.ts

echo
echo "== route files mentioning current library id around routes =="
rg -n '(^\s*id:\s*|export default|redirects|versions=|version\.routes|availableVersions|/\w+/docs|docs\.framework|table/') src/routes src/components src/libraries tests/docs-route-smoke.test.ts -g '*.ts' -g '*.tsx' | sed -n '1,220p'

echo
echo "== package references =="
rg -n '`@tanstack/table`|tanstack-table|Table' package.json README.md src -g '*.ts' -g '*.tsx' -g '*.md' | sed -n '1,200p'

Repository: TanStack/tanstack.com

Length of output: 1773


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('src/libraries/libraries.ts')
text = p.read_text()
needle = "latestVersion: 'v9'"
idx = text.find(needle)
if idx < 0:
    raise SystemExit('v9 latest not found')
# Print compact context without relying on exact line count outside.
start = text.rfind('\nexport const libraries', 0, idx)
end = idx + 2000
print(text[start:end])
PY

Repository: TanStack/tanstack.com

Length of output: 160


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== candidate route files =="
git ls-files 'src/routes/**/table*' 'src/routes/*-library*' 'src/routes/_library*' 'tests/docs-route-smoke.test.ts' | sed -n '1,120p'

echo
echo "== precise route/id/redirect searches =="
rg -n --glob '*.ts' --glob '*.tsx' \
  "id: ['\"]table['\"]|\\$libraryId|\\$version|availableVersions|redirects|latestVersion|/table/(v9|beta|v8|latest)" \
  src/routes tests/docs-route-smoke.test.ts | sed -n '1,260p'

Repository: TanStack/tanstack.com

Length of output: 2609


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== library index metadata =="
sed -n '1,140p' src/routes/_library/$libraryId/index.tsx

echo
echo "== route metadata and version routing =="
sed -n '1,140p' src/routes/_library/$libraryId/$version.tsx
sed -n '1,150p' src/routes/_library/$libraryId/route.tsx

echo
echo "== smoke test routing expectations =="
sed -n '1,120p' tests/docs-route-smoke.test.ts

echo
echo "== docs cache headers version handling =="
sed -n '1,120p' src/utils/docs-cache-headers.ts

echo
echo "== redirect banner handling =="
sed -n '1,140p' src/components/RedirectVersionBanner.tsx
sed -n '1,140p' src/components/VersionSelect.tsx

Repository: TanStack/tanstack.com

Length of output: 230


🏁 Script executed:

#!/usr/bin/env bash
set -euo pfile

find src/routes/_library -maxdepth 2 -type f | sort

echo "== library metadata =="
find src/routes/_library -maxdepth 2 -type f \( -name "index.tsx" -o -name "route.tsx" -o -name "\\$version.tsx" \) -print | sort | while read -r f; do
  echo "--- $f"
  sed -n '1,180p' "$f"
done

echo "== smoke test =="
sed -n '1,120p' tests/docs-route-smoke.test.ts

Repository: TanStack/tanstack.com

Length of output: 205


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

find src/routes/_library -maxdepth 2 -type f | sort

echo "== library metadata =="
find src/routes/_library -maxdepth 2 -type f \( -name "index.tsx" -o -name "route.tsx" -o -name "\$version.tsx" \) -print | sort | while read -r f; do
  echo "--- $f"
  sed -n '1,180p' "$f"
done

echo "== smoke test =="
sed -n '1,120p' tests/docs-route-smoke.test.ts

Repository: TanStack/tanstack.com

Length of output: 9244


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

echo "== docs config loader =="
rg -n --glob '*.ts' --glob '*.tsx' "docsConfigQueryOptions|docsConfigs|docsConfigsQuery" src -A30 -B10

echo
echo "== route config/build output for docs files =="
rg -n --glob 'configs.*ts' --glob '*.config.*ts' --glob '*.mts' "validateLibraryVersion|createDocsConfig|docs_configs|docsConfig" . -A20 -B10 | sed -n '1,260p'

echo
echo "== find docs config source files =="
git ls-files | rg 'docs?config|docs-config|config|docs_contents|generated|docs_configs|version' | sed -n '1,200p'

Repository: TanStack/tanstack.com

Length of output: 11950


🏁 Script executed:

#!/usr/bin/env bash
set -Eu pipefail

echo "== validateLibraryVersion implementation =="
rg -n --glob '*.ts' --glob '*.tsx' "function validateLibraryVersion|export function validateLibraryVersion|const validateLibraryVersion" src -A60 -B10

echo
echo "== docs config client/fetch implementation =="
rg -n --glob '*.ts' --glob '*.tsx' "function getTanstackDocsConfig|async function getTanstackDocsConfig|getTanstackDocsConfig|getDocsConfigRequest" src -A60 -B10

echo
echo "== table docs config files/content refs =="
git ls-files | rg 'table|docs' | rg -i 'table|docs|content|config|source|src' | sed -n '1,300p'

Repository: TanStack/tanstack.com

Length of output: 17655


🏁 Script executed:

#!/usr/bin/env bash
set -u pipefail

echo "== library config branch/resolution helpers =="
rg -n --glob '*.ts' --glob '*.tsx' "function getBranch|const getBranch|export function getBranch|export const getBranch" src -A80 -B10

echo
echo "== cache headers =="
sed -n '1,120p' src/utils/docs-cache-headers.ts

echo
echo "== docs redirect handling =="
rg -n --glob '*.ts' --glob '*.tsx' "getDocsRedirect|redirects|handleRedirects|availableVersions|available" src/utils docs src/components src/routes -A30 -B10 | sed -n '1,320p'

Repository: TanStack/tanstack.com

Length of output: 22518


🏁 Script executed:

#!/usr/bin/env bash
set -u pipefail

echo "== remote tanstack/table branch existence for v9, beta, main =="
for branch in v9 beta main; do
  branch_url="https://api.github.com/repos/TanStack/table/git/ref/refs/heads/$branch"
  echo "--- $branch"
  curl -fsSL "$branch_url" | jq '{ref, object_type: .object.type, sha}' || echo "missing or not JSON"
done

echo
echo "== remote docs/config.json for current branches =="
for branch in v9 beta main; do
  echo "--- $branch"
  curl -fsSL "https://raw.githubusercontent.com/TanStack/table/$branch/docs/config.json" | jq '{version: .version}' || { echo "missing"; curl -fsSLI "https://raw.githubusercontent.com/TanStack/table/$branch/docs/config.json"; }
done

Repository: TanStack/tanstack.com

Length of output: 565


Resolve the V9 docs branch before changing table metadata.

latestVersion now points to v9, and availableVersions includes v9 and beta, but the route model only validates latest plus explicit versions once docs/config.json is fetched for the resolved branch. Confirm that TanStack Table has a v9 docs branch and rename or drop beta so /table/beta does not become unexpected content.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/libraries/libraries.ts` around lines 313 - 315, Update the table metadata
around latestVersion, latestBranch, and availableVersions only after verifying
that the TanStack Table v9 documentation branch exists; use the resolved branch
configuration to ensure latest and explicit versions validate correctly, and
rename or remove beta so /table/beta cannot serve unintended content.

Comment thread src/libraries/table.tsx
Comment on lines +69 to 82
title: 'Reactive by Design',
icon: <LightningIcon className={twMerge(textStyles)} />,
description: (
<div>
Don't be fooled by the small bundle size. TanStack Table is a
workhorse. It's built to materialize, filter, sort, group, aggregate,
paginate and display massive data sets using a very small API surface.
Wire up your new or existing tables and{' '}
Every registered state slice is backed by TanStack Store, whose
fine-grained reactivity is built on alien-signals. Read a selected
snapshot, subscribe exactly where state is rendered, or own a slice
with an external atom.{' '}
<span className={twMerge('font-semibold', textStyles)}>
watch your users become instantly more productive
Fine-grained reactivity keeps unrelated parts of a large table out
of the render path.
</span>
.
</div>
),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀 Performance & Scalability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== repo files around table.tsx =="
fd -a 'table\.tsx$' . | sed 's#^\./##' | head -50

echo "== target lines =="
if [ -f src/libraries/table.tsx ]; then
  nl -ba src/libraries/table.tsx | sed -n '1,120p'
fi

echo "== TanStack dependencies in manifests =="
python3 - <<'PY'
import json, pathlib
for p in pathlib.Path('.').glob('**/package.json'):
    if 'node_modules' in p.parts or '.git' in p.parts:
        continue
    try:
        data=json.loads(p.read_text())
    except Exception as e:
        continue
    hits=[]
    for sec in ('dependencies','devDependencies','peerDependencies'):
        for k,v in data.get(sec,{}).items():
            if '`@tanstack`' in k:
                hits.append((sec,k,v))
    if hits:
        print(p)
        for sec,k,v in hits:
            print(f'  {sec}: {k}={v}')
PY

Repository: TanStack/tanstack.com

Length of output: 354


🌐 Web query:

TanStack Table V9 React state selector default selector whole table state renders granular subscription

💡 Result:

In TanStack Table v9, the state management system has been overhauled to utilize TanStack Store, enabling granular reactivity and optimized rendering [1][2]. Default Rendering Behavior By default, the hook useTable (or useReactTable) subscribes to the entire table state [3][4]. Consequently, any change to any part of the registered state triggers a re-render of the component that owns the table [3][4]. This behavior is equivalent to using a default selector of state => state [4]. Granular Subscriptions To avoid re-rendering the whole table for every state change, TanStack Table v9 introduces opt-in mechanisms to narrow the subscription surface [2][3][5]. 1. Custom Selectors in useTable: You can pass a selector function as the second argument to useTable to restrict which state slices trigger a re-render of the table component [3][4]. For example, if you only want to re-render the main table component when pagination changes, you can return { pagination: state.pagination } [4]. 2. table.Subscribe: For isolated components (such as a row-selection checkbox or a page-indicator widget), you can use the table.Subscribe component or the useSelector hook from @tanstack/react-store [2][6][5]. This allows these specific parts of the UI to subscribe only to the precise slice of state they require, such as table.atoms.rowSelection [1][3][5]. 3. Per-Slice Atoms: Each state slice (e.g., sorting, filtering, row selection) is backed by its own atom [3][5]. Accessing these via table.atoms.<slice> provides the narrowest possible subscription surface, as it skips constructing the full state snapshot and only triggers updates when that specific slice changes [2][5][7]. Migration Note The v8-style global onStateChange callback is removed in v9 [1]. If you require fine-grained control, the recommended pattern is to shift from subscribing to the whole table state at the top level to using table.Subscribe or useSelector closer to the components that actually consume the data [4]. For extreme performance requirements, such as high-frequency updates (e.g., column resizing), you can pass a constant selector (e.g., () => ({})) to the table hook to disable its subscription entirely, moving updates to CSS variables or localized table.Subscribe islands [8]. Top Results: [1][2][3][4][8]

Citations:


Qualify the fine-grained rendering claim.

TanStack Table React hooks subscribe to the full table state by default. Narrow selectors or isolated subscriptions make unrelated table parts avoid re-rendering on every state change. Add the condition before this promise.

Suggested wording
-            Fine-grained reactivity keeps unrelated parts of a large table out
-            of the render path.
+            With a narrow selector or subscription, fine-grained reactivity can
+            keep unrelated parts of a large table out of the render path.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
title: 'Reactive by Design',
icon: <LightningIcon className={twMerge(textStyles)} />,
description: (
<div>
Don't be fooled by the small bundle size. TanStack Table is a
workhorse. It's built to materialize, filter, sort, group, aggregate,
paginate and display massive data sets using a very small API surface.
Wire up your new or existing tables and{' '}
Every registered state slice is backed by TanStack Store, whose
fine-grained reactivity is built on alien-signals. Read a selected
snapshot, subscribe exactly where state is rendered, or own a slice
with an external atom.{' '}
<span className={twMerge('font-semibold', textStyles)}>
watch your users become instantly more productive
Fine-grained reactivity keeps unrelated parts of a large table out
of the render path.
</span>
.
</div>
),
title: 'Reactive by Design',
icon: <LightningIcon className={twMerge(textStyles)} />,
description: (
<div>
Every registered state slice is backed by TanStack Store, whose
fine-grained reactivity is built on alien-signals. Read a selected
snapshot, subscribe exactly where state is rendered, or own a slice
with an external atom.{' '}
<span className={twMerge('font-semibold', textStyles)}>
With a narrow selector or subscription, fine-grained reactivity can
keep unrelated parts of a large table out of the render path.
</span>
</div>
),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/libraries/table.tsx` around lines 69 - 82, Update the “Reactive by
Design” description to qualify the fine-grained rendering claim: state that
unrelated table parts avoid re-rendering when narrow selectors or isolated
subscriptions are used, rather than presenting it as the default behavior of
TanStack Table React hooks. Keep the surrounding reactivity explanation
unchanged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant