Knowledge base from the official TanStack Table v9 documentation (tanstack.com/table) — headless table/datagrid library with framework adapters for React, Vue, Solid, Svelte, Angular, and more. Use when building or debugging a data table/grid, choosing between client-side and server-side row processing, wiring up sorting/filtering/pagination/grouping/selection/pinning/sizing, working with the v9 tableFeatures plugin architecture, migrating from v8's useReactTable, or writing a custom table feature. Priorizes the React adapter (@tanstack/react-table); other frameworks get brief compatibility notes only.
Package: @tanstack/table-core (+ per-framework adapters, primarily @tanstack/react-table) | Chapters: 54 (10 Overview/Handbook + 19 Feature Guides + 8 API Reference, headless, React-focused) | Generated: 2026-08-25
sorting, row selection, column pinning, etc.; I find and read the matching chapter.ch035; I load that specific chapter.useTable, tableFeatures, createColumnHelper, FlexRender, etc.; I find the chapter that defines/uses it.When you ask about a topic not covered in Core Patterns below, I will read the relevant chapter file before answering.
Headless, always. This library renders nothing — no markup, no CSS. useTable() returns a table instance with state and getters (table.getHeaderGroups(), table.getRowModel().rows); you write every <table>/<div> element yourself.
Everything is opt-in via tableFeatures({...}). v9's plugin architecture means a table with tableFeatures({}) has only core row/column/cell construction — no sorting, filtering, pagination, anything. Register exactly the features (rowSortingFeature, columnFilteringFeature, ...) a table needs; unregistered features' state/APIs don't exist on the type, and their code doesn't ship in the bundle.
Feature ≠ row model ≠ function registry — three separate slots. A feature (rowSortingFeature) adds state/options/APIs. A row-model factory (sortedRowModel: createSortedRowModel()) does the actual client-side data processing — omit it and set the matching manual*: true flag for server-side processing while keeping the feature's state/APIs. A function registry (sortFns, filterFns, aggregationFns) supplies named implementations referenced by string in column defs — register individually, never spread the full built-in registry (it defeats tree-shaking).
State is TanStack Store atoms. table.atoms.<slice>.get() reads without subscribing; useTable's selector argument (default: everything) or table.Subscribe (scoped to a slice/atom) is what triggers re-renders. Own a slice externally via the atoms table option (v9-recommended) or the classic state/on[X]Change pair.
row/cell/column/header are stable references — read their state-dependent methods inside a Subscribe, not just their props. A nested component receiving only row as a prop can be memoized by React/the compiler even when row.getIsSelected() would now return something different. This is the one recurring gotcha across selection, sorting, pinning, and every other stateful feature.
Fixed row-model pipeline order: filter → group → sort → expand → paginate (row pinning and column ordering/pinning/grouping have their own separate, also-fixed reorder pipelines).
Always render through FlexRender (table.FlexRender / <FlexRender .../>), never by reading columnDef.header/.cell directly — it's a template (string, node, or function) and FlexRender resolves it correctly, including cell-vs-aggregatedCell and grouping-placeholder logic.
| # | Title | Key Concepts |
|---|---|---|
| ch001 | Introduction | headless UI, framework-agnostic core, TanStack ecosystem composition |
| ch002 | Framework Adapters & Installation | @tanstack/react-table, per-framework packages, devtools install |
| ch003 | Devtools | table key, TanStackDevtools, useTanStackTableDevtools |
| ch004 | Agent Skills (TanStack Intent) | npx @tanstack/intent install, node_modules SKILL.md guidance |
| # | Title | Key Concepts |
|---|---|---|
| ch005 | Quick Start (React) | tableFeatures, useTable, FlexRender, first sortable table |
| ch006 | Migrating to TanStack Table V9 (React) | useReactTable→useTable, features option, breaking changes |
| ch007 | Using useLegacyTable for Incremental Migration | @tanstack/react-table/legacy, deprecated bridge |
| # | Title | Key Concepts |
|---|---|---|
| ch008 | Features Guide | stockFeatures, feature/row-model/function split |
| ch009 | Data Guide | TData, stable reference, deep keys, subRows |
| ch010 | Client-Side vs Server-Side Guide | manual* flags, when to go server-side |
| ch011 | Column Definitions Guide | accessor/display/group columns, createColumnHelper |
| ch012 | Table Instance Guide | table creation across adapters, atoms/store |
| ch013 | Row Models Guide | pipeline order, create*RowModel slots |
| ch014 | Worker Row Models Guide (Experimental) | Web Worker offloading, 100k+ rows |
| ch015 | Rows Guide | getRowId, getDisplayIndex, row.original |
| ch016 | Cells Guide | cell.getValue, FlexRender for cells |
| ch017 | Header Groups Guide | multi-row headers |
| ch018 | Headers Guide | colSpan/rowSpan, header row spanning |
| ch019 | Columns Guide | column objects vs. rendering |
| ch020 | Table and Column Meta Guide | metaHelper, tableMeta/columnMeta/filterMeta |
| ch021 | Helpers Guide | tableFeatures, tableOptions, createColumnHelper |
| ch022 | Table State (React) Guide | atoms, selectors, Subscribe, external atoms |
| ch023 | React Compiler Guide | stable references, Subscribe for nested components |
| ch024 | Composable Tables (createTableHook) Guide | useAppTable, shared components |
| ch025 | Table Context Guide | useTableContext/useCellContext/useHeaderContext |
| ch026 | FlexRender (React) Guide | FlexRender vs flexRender |
| ch027 | Custom Features (React) Guide | TableFeature, writing a plugin |
| # | Title | Key Concepts |
|---|---|---|
| ch028 | Cell Selection (React) Guide | range operation log, drag/Shift/Ctrl selection |
| ch029 | Cell Spanning (React) Guide | spanRows, spanColumns, stateless merges |
| ch030 | Column Ordering (React) Guide | columnOrder, DnD, order pipeline |
| ch031 | Column Pinning (React) Guide | start/center/end, sticky CSS vs. split tables |
| ch032 | Column Sizing (React) Guide | size/minSize/maxSize |
| ch033 | Column Resizing (React) Guide | resize mode, performant resizing |
| ch034 | Column Visibility (React) Guide | columnVisibility map, getVisible* APIs |
| ch035 | Column Filtering (React) Guide | 18 built-in filterFns, constructFilterFn |
| ch036 | Global Filtering (React) Guide | globalFilterFn, 12 built-ins |
| ch037 | Fuzzy Filtering (React) Guide | match-sorter-utils, filterMeta + paired sort |
| ch038 | Faceting (React) Guide | facet excludes own filter, bucketing |
| ch039 | Aggregation (React) Guide | getAggregationValue, custom definitions |
| ch040 | Grouping (React) Guide | grouping state, groupedColumnMode |
| ch041 | Expanding (React) Guide | getSubRows vs. getRowCanExpand |
| ch042 | Pagination (React) Guide | pageIndex/pageSize, cursor pagination |
| ch043 | Row Pinning (React) Guide | top/center/bottom |
| ch044 | Row Selection (React) Guide | getRowId, Shift range, deselectParents |
| ch045 | Sorting (React) Guide | 6 built-in sortFns, invertSorting, multi-sort |
| ch046 | Virtualization (React) Guide | @tanstack/react-virtual, not a Table feature |
| # | Title | Key Concepts |
|---|---|---|
| ch047 | Core Table Types | Table, TableOptions, TableState, TableFeature |
| ch048 | React Adapter API | useTable, ReactTable, Subscribe, FlexRender |
| ch049 | Column & Cell Types | ColumnDef variants, Cell/Header/Context types |
| ch050 | Row Model Factories | the 7+ create*RowModel functions |
| ch051 | Feature Flags Reference | every *Feature export, one table |
| ch052 | Filter/Sort/Aggregation Function Types | FilterFn, SortFn, AggregationFn* types |
| ch053 | State Types Reference | every state slice's type, one table |
| ch054 | Legacy API (v8 Compatibility) | @tanstack/react-table/legacy full reference |
This skill covers the TanStack Table v9 documentation as of the fetch date in the source, prioritizing the React adapter (@tanstack/react-table) — matching this project's own stack. Other framework adapters (Vue, Solid, Svelte, Angular, Ember, Lit, Alpine, vanilla) exist and share the same core concepts/state model, but their framework-specific syntax is not covered in depth; see ch002 for the package name and minimum version per framework, and the Composability sections of ch001/ch010 for how the framework-agnostic core relates to each adapter.
This is a headless table library — it renders no markup or styles. It pairs naturally with a styling/component layer (Tailwind, shadcn/ui, Radix/Base UI for building custom cell controls) and with react-hook-form-docs for editable-cell forms, tanstack-query-docs (if present in this library) for server-state fetching feeding server-side row processing, and react-docs (if present) for general React 19 patterns underlying every hook in this skill.
Worker Row Models (ch014) is explicitly marked experimental by the source and should be treated as a last resort for 100,000+ client-side rows, not a default optimization.