Chapter 1: Introduction
Core Idea
TanStack Table is a headless table/datagrid library: it owns state, row/column processing, and APIs, but renders no markup or styles at all — you build the <table> yourself from the table instance's state and getters, so you keep 100% control over markup, styling, and behavior.
Key Concepts
- Headless UI: the library provides logic/state/processing, never markup or CSS. You call
table.getHeaderGroups() / table.getRowModel().rows and render however you want (any CSS framework, any component library, or none).
- Framework-agnostic core: most logic lives in framework-agnostic TypeScript (
@tanstack/table-core). Official adapters wire that core into React (@tanstack/react-table), Preact, Solid, Svelte, Vue, Angular, Ember, Ember Octane, Lit, Alpine, or vanilla JS directly.
- Modular / tree-shakeable: v9's full package is ~25 KB minified+Brotli, but you only register the features and row models your table actually uses — unused optional capabilities tree-shake away.
- Feature system: sorting, filtering, pagination, grouping, pinning, selection, resizing, etc. are all opt-in "features" registered on the table, plus a custom feature (plugin) system for your own state/APIs (see Custom Features).
- Composability with the TanStack ecosystem: TanStack Virtual (virtualize rows/columns), TanStack Query (server-state fetching/caching for manual pagination/sorting/filtering), TanStack Form (editable cells/inline editing), TanStack Pacer (debounce/throttle filter inputs), TanStack Store (powers table state internally; you can supply your own atoms).
Code Examples
// The headless pattern: build your own markup from the table instance
const table = useTable({ features, columns, data })
return (
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (/* your header markup */ null))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (/* your row markup */ null))}
</tbody>
</table>
)
- What it demonstrates: no pre-built
<DataGrid> component with theme props — you own every element, so anything (virtualization, custom cell editors, drag handles) drops in without fighting a component's prop API.
Key Takeaways
- TanStack Table is an engine, not a component — expect to write your own
<table> markup, not import a styled grid.
- The core is framework-agnostic; this skill focuses on the React adapter (
@tanstack/react-table / useTable), the project's stack — other frameworks are noted only where genuinely different.
- Because state can be lifted out of the table (into URL params, a global store, TanStack Query, etc.), server-side pagination/sorting/filtering is a first-class use case, not a workaround.
- Reach for TanStack Virtual alongside this library for large row counts — table logic itself doesn't change when virtualization is added.
Connects To
- Framework Adapters & Installation: package names and setup per framework.
- Custom Features (React) Guide: how the plugin system extends the table instance.
- Data Guide / Column Definitions Guide: the two inputs every table needs.