npm / @tanstack/table-core
@tanstack/table-core
What changed in @tanstack/table-core 9, from its official release notes, upgrade guides and advisories. Sources checked 2026-11-12.
39 breaking3 deprecations22 new APIs and options2 performance2 behavior and defaults2 tooling7 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli init@tanstack/table-core 977 changes
Breaking changes 39
Without globalFilteringFeature, global facets include no columns, matching the filtered row model.
Bundled skills are split into smaller entry points, with feature and composition references loaded as needed. Consumers with individual skill permissions or explicit agent mappings must replace retired IDs and refresh mappings.
Grouped and downstream worker flatRows now use parent-first preorder.
Register aggregation functions in the tableFeatures registry slot instead of augmenting AggregationFns.
getAggregationFn is replaced by getAggregationFns because a column can run multiple aggregation definitions.
getAggregationValue now accepts a single options object containing rows and maxDepth instead of positional arguments.
ColumnMeta declaration merging now takes TFeatures as its first type parameter.
Column pinning uses logical start/end terminology instead of left/right, with no deprecated aliases; update state values, pin arguments, and related column, row, and table APIs.
Column pinning uses start/end terminology, including columnPinning.start and column.pin('end').
The former columnSizingInfo state and setter are now columnResizing and setColumnResizing, with onColumnResizingChange replacing onColumnSizingInfoChange.
Column sizing and interactive resizing are separate features, so tables can register only sizing or add columnResizingFeature when drag-to-resize is needed.
Custom aggregation callables now use context-based definitions with aggregate and context.rows; maxAggregationDepth controls the selected aggregation depth.
Convert custom aggregation callables to constructAggregationFn({ aggregate, merge? }) definitions.
Creates a filtered row model for registration on tableFeatures instead of configuring a separate table option.
Creates a paginated row model for registration on tableFeatures instead of configuring a separate table option.
Creates a sorted row model for registration on tableFeatures instead of configuring a separate table option.
The enablePinning option is split into separate column- and row-pinning options.
Packages ship as modern ESM; UMD and CJS builds have been dropped.
A required useTable option declares which features, row models, and processing functions the table uses.
Register filter functions in the tableFeatures registry slot instead of augmenting FilterFns; registered keys typecheck as string references.
Use the filterMeta feature slot to type filter metadata without augmenting FilterMeta.
Move get*RowModel() options into tableFeatures slots, such as filteredRowModel: createFilteredRowModel().
Table state is accessed through table.state, table.store, or state-slice atoms instead of the Table V8 getState method.
The table option was removed; subscribe to table.store for notifications of any state change. Individual on[State]Change handlers remain available.
Methods are shared on object prototypes rather than created per instance, so destructuring them loses the this context and they are not own properties.
When rowSelectionFeature is enabled, the handler now supports inclusive Shift range selection by default; set enableRowRangeSelection to false to retain the previous non-range behavior.
Call row methods on the row instance rather than using destructured row methods.
Aggregation is independent from column grouping; explicitly registered features must include rowAggregationFeature when columns use aggregation APIs.
RowData is restricted to Record<string, any> or Array<any>, so unusual data types must conform to one of those shapes.
Sorting APIs were renamed for consistency: column definitions use sortFn, and related methods, types, and built-in functions use SortFn, getSortFn, getAutoSortFn, SortFns, and sortFns.
Column definitions use sortFn in place of sortingFn.
Register sort functions in the tableFeatures registry slot instead of augmenting SortFns.
Internal APIs prefixed with an underscore have been removed, including _getPinnedRows and the listed faceting methods.
This check now returns true whenever at least one row is selected, including when all rows are selected; the page-row counterpart follows the same rule.
Access state through table.store.state or table.state instead of table.getState().
Registers table features, row model factories, and processing function registries, enabling unused code to be tree-shaken.
Separate export for legacy-specific APIs, including useLegacyTable and legacy helpers.
Most types now require TFeatures as a generic parameter, changing the generic shapes for table, column, row, cell, and definition types.
Replaces useReactTable as the React hook for creating a table, consistent with hook naming across TanStack libraries.
Deprecations 3
The full registry export is deprecated in favor of individual aggregationFn_* imports or functions supplied directly in column definitions.
The full registry export is deprecated in favor of individual filterFn_* imports or functions supplied directly in column definitions.
The full registry export is deprecated in favor of individual sortFn_* imports or functions supplied directly in column definitions.
New APIs and options 22
Adds table.autoResetSorting().
Adds getCanLastPage for detecting whether a finite last page can be reached.
Lets callers supply writable atoms for state slices to own that state externally.
Adds spreadsheet-style rectangular cell range selection, including drag, Shift-extend, and multiple disjoint ranges.
Adds body-cell spanning across rows and columns, with span-aware cell selection and header rowSpan computation.
The new columns() helper preserves individual column TValue types across wrapped arrays and nested group columns.
Declare column metadata types per table using the columnMeta feature slot, without global declaration merging.
Creates custom table hooks with pre-bound features and components for reusable app-level table patterns.
Provides all features for useTable as a shortcut for Table V8-like behavior, with a larger bundle.
Exposes per-slice readonly atoms for narrow subscriptions to individual table state slices.
A component-based rendering API is available on the table instance for headers, cells, and footers; the existing flexRender function still works.
Provides the selected table state, which contains all registered state by default or the state shape returned by a custom useTable selector.
Exposes a framework-agnostic store of the entire table state for one-off reads and fine-grained subscriptions.
Enables fine-grained reactive subscriptions so rendered content only updates when selected state changes.
Define table features with tableFeatures(), or use stockFeatures.
Declare metadata types per table using the tableMeta feature slot, without global declaration merging.
Enables composition of reusable table configuration, including features, row models, and default options.
The tableOptions helper provides type-safe composition of reusable partial table configurations, including options that omit required fields.
Components registered via createTableHook can access cell context with useCellContext.
Components registered via createTableHook can access header context with useHeaderContext.
Provides a temporary migration hook that accepts the Table V8-style API; it is deprecated and includes all features by default.
Components registered via createTableHook can access table context with useTableContext.
Performance 2
The core and unregistered features bundle less unrelated code, reducing the size of a minimal table by about 0.27 kB (brotli).
Importing one built-in filter, sort, or aggregation function now bundles only that function; row models also avoid importing code from unregistered features, reducing bundle size.
Behavior and default changes 2
Page size now supports Infinity, allowing an unbounded page size.
The former private row._getAllCellsByColumnId method is now public as row.getAllCellsByColumnId.
Tooling 2
The devtools panel now displays measured minified and brotli sizes for each feature, row model, and built-in function, with shared code accounted for in the total.
Compiled output now targets ES2022.
Fixes and other changes 7
Private declarations are kept out of emitted declaration files, preventing TS2883 failures for consumers emitting declarations.
The table type now declares getOrderColumnsFn(), which column ordering already assigned.
Corrects the type to declare autoResetPageIndex rather than _autoResetPageIndex, matching the method the table actually has.
Missing core rows are skipped when rebuilding a worker row-model payload, preventing stale worker results from crashing the table.
Hierarchical filtered row models now list parents before descendants in both filtering modes, preserve filter metadata on cloned rows, and round-trip nested data through worker-backed row models.
Equality-guarded state slices return the existing reference for semantically unchanged updates, helping controlled-state consumers avoid unnecessary re-renders and auto-reset render loops. Custom onXChange handlers are still invoked, and the state owner evaluates updaters once.
The flattened sorted rows now list parents before sub-rows, matching the sorted rows tree and other row models.