# TanStack Table: a headless table library for TypeScript, and what you give up for the control

> TanStack Table ships one framework-agnostic core with adapters for React, Vue, Solid, Svelte, Angular, Ember, Lit, Alpine and others. It renders nothing, so every pixel of the grid is your code, and so is every accessibility decision.

**TanStack/table** — Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table.

- Repository: https://github.com/TanStack/table
- Website: https://tanstack.com/table
- Stars: 28,459 · Forks: 3,583
- Language: TypeScript
- License: MIT
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/tanstack-table

## What TanStack Table solves, and for whom

The problem is not sorting. Sorting an array is a one-liner. The problem is that every team building a data-heavy screen ends up writing the same state machine: which column is sorted and in which direction, which filters are active, which rows are expanded, which are selected, which page you are on, and how all of that survives a refetch. TanStack Table packages that state machine. The README describes it as a headless table library for building datagrids with full control over markup, styles, and behavior, and the adapter list is the giveaway: React, Preact, Octane, Vue, Solid, Svelte, Angular, Ember, Lit and Alpine, all driven by a framework-agnostic core.

The audience is narrower than the download numbers suggest. It is for engineers who already have a component library and do not want a grid vendor's CSS fighting it. If you are happy to accept someone else's theme, someone else's DOM and someone else's keyboard handling, a batteries-included grid is less work. TanStack Table is for the case where the table has to look like the rest of your application and behave the way your accessibility audit demands, and where you would rather own that than configure around it.

## The headless core and the adapter packages

The repository is a pnpm workspace with a packages directory and a separate examples directory per framework (examples/react/, examples/vue/, examples/svelte/, examples/angular/, examples/solid/, examples/preact/, examples/alpine/, examples/ember/, examples/lit/, examples/octane/, examples/vanilla/). The published artifacts follow the same split: @tanstack/table-core, plus @tanstack/react-table, @tanstack/vue-table, @tanstack/svelte-table and the rest. The recent releases listed for the repository are @tanstack/vue-table@9.2.4, @tanstack/table-core@9.2.4 and @tanstack/svelte-table@9.2.4, all dated 2026-08-28, so the adapters move in lockstep with the core.

The mechanism is a hook. You call useReactTable (or the Vue, Svelte, Solid equivalent) with your data and your column definitions, and you get back an instance object. That instance does not render. It exposes methods such as getHeaderGroups and getRowModel, and you map over their output to produce your own table, thead, tbody and td elements. The README's own summary of the feature set is sorting, filtering, grouping, aggregation and row selection, and it notes the library is lightweight, virtualizable and server-side friendly. Server-side friendly matters more than it sounds: because the core only computes state and model, you can feed it a page of rows from an API and let the server do the sorting and filtering, and the client-side logic still drives the UI.

The trade-off is visible immediately. A headless library cannot ship a default empty state, a default loading skeleton, or a default column resize handle. All of that is markup you write. The documentation is explicit that you bring your own UI, components and styles; it is less explicit about how much of that work is accessibility rather than appearance.

## Installing it and rendering a first table

The README points to the docs site at tanstack.com/table for setup, and the repository's examples directory contains a runnable project per framework. The command below is the one the README gives for adding the agent skills that ship inside each adapter package, and it is the only install command the README prints:

```bash
npx @tanstack/intent@latest install
```

The README states that this adds skill-loading guidance for your agent (Claude Code, Cursor, Copilot, etc.), that the same CLI exposes intent list to browse available skills and intent load <skill> to print one for inspection, and that it is only available for v9 and above. For the library itself, the README's npm badge points at @tanstack/react-table and the setup instructions live at tanstack.com/table, so the package name you install is the adapter matching your framework: @tanstack/react-table, @tanstack/vue-table, @tanstack/svelte-table and the others in the adapter list.

Once installed, the shape is the same in every adapter. You define an array of column definitions, pass it with your data to the adapter's table hook, and receive back an instance that exposes model getters. You then map over getHeaderGroups for the header row and over getRowModel for the body rows, writing the table, thead, tbody and td elements yourself. What you should see after that first render is a plain HTML table with no styling and no interactive controls, because the library adds none.

## Where the headless approach costs you time

The honest limitation is that TanStack Table is not a datagrid. It is the logic layer of one. The README lists grouping, aggregation and row selection as features, which is accurate, but each arrives as state and model output rather than as a finished interaction. Row selection gives you selected row IDs and a toggle handler; the checkbox, its indeterminate state, its label and its relationship to the header select-all control are yours. Column resizing gives you a size value; the drag handle, the pointer events and the minimum width guard are yours.

Accessibility is the sharpest edge. A table built from map calls has no aria-sort on the sorted column, no scope on header cells, no announcement when a filter reduces the row count, unless you add them. None of that is a defect in the library, and the documentation does not claim otherwise, but teams adopting it on the strength of the feature list frequently discover the gap after the first audit. The same applies to virtualisation: the README says the library is virtualizable, and the TanStack ecosystem includes TanStack Virtual, but the two are separate packages and the integration is code you write.

There is also a version boundary worth noting. The README states that the TanStack Intent skills shipped inside each adapter package are only available for v9 and above, and the current releases are 9.2.4. If you are pinned to an older major, that tooling is not part of your install.

## TanStack Table compared with a batteries-included grid

The clearest alternative in the same ecosystem is AG Grid, which the README itself lists among the project's partners, and the difference is not quality but where the boundary sits. AG Grid ships the rendered grid: header cells, sort indicators, filter popovers, column menus, row grouping UI and a theme layer. You configure it. TanStack Table ships none of that; you render it.

The practical consequence shows up in two places. First, styling: with AG Grid you override a theme, with TanStack Table you write the table element and the CSS from scratch, which is faster if your design system is strict and slower if it is not. Second, feature integration: sorting, filtering and grouping in a rendered grid are wired together by the vendor, so combinations work out of the box. In TanStack Table each feature is a plugin you compose, and the composition is your responsibility. That is the same trade-off as headless UI generally, and it is a real one rather than a marketing distinction.

A second alternative is writing the table yourself with no library. For a static list of twenty rows that is the right call. TanStack Table starts paying for itself when the state machine grows past sorting into filters, pagination, selection and server round trips.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-08-28. The default branch is beta, which is worth knowing before you clone it expecting main. Versioning is handled with changesets: the root package.json defines changeset, changeset:version and changeset:publish scripts, and changeset:version runs pnpm install --no-frozen-lockfile followed by a skills version fix and a format pass. In practice this means releases are batched and the adapter packages are versioned together, so upgrading @tanstack/react-table and @tanstack/table-core to the same minor is the normal path.

The repository itself is a pnpm workspace and requires Node 20 or newer, with pnpm 11.9.0 or newer, per the engines field. That constraint applies to contributors building from source, not to consumers installing the published packages, but it tells you the toolchain is modern and that older CI images will fail on a fresh clone.

Licensing is MIT. That permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. This is a statement about what the licence text allows, not legal advice; if you are vendoring the source into a closed product, have your own counsel read the LICENSE file at the repository root.

## Conclusion

Adopt TanStack Table if you already have a design system, need server-side sorting and filtering, and are willing to write the table markup and keyboard behaviour yourself. Do not adopt it if you want a working grid in an afternoon, or if you need grouping, pinning and virtualisation to arrive already wired together. Before committing, check that your framework has an adapter package at 9.2.4, that your Node version satisfies engines, and that you can render a header and one body row with getHeaderGroups and getRowModel.

## FAQ

### What is TanStack Table?

It is a headless table library for building datagrids with full control over markup, styles and behavior, as the README puts it. A framework-agnostic core is paired with bindings for React, Preact, Octane, Vue, Solid, Svelte, Angular, Ember, Lit and Alpine.

### How can I create a table with TanStack Table?

Install the adapter for your framework, define columns with the column helper, call the adapter hook with your data, columns and getCoreRowModel, then map over getHeaderGroups and getRowModel to render your own table markup.

### How do I install TanStack Table?

The README's npm badge points at @tanstack/react-table, and the repository publishes matching adapter packages such as @tanstack/vue-table and @tanstack/svelte-table. The README directs setup questions to the docs at tanstack.com/table.

### Does TanStack Table render any UI for me?

No. The README describes it as headless and says you bring your own UI, components and styles. The instance exposes methods like getHeaderGroups and getRowModel, and the table, thead and tbody elements are yours to write.

### Does TanStack Table work with server-side data?

The README lists the library as server-side friendly, and because the core computes state and models rather than rendering, you can supply a page of rows from an API and let the server handle sorting and filtering.

## Sources

- [Official documentation](https://tanstack.com/table)
- [Official README](https://github.com/TanStack/table#readme)
- [Project repository](https://github.com/TanStack/table)
- [Release notes](https://github.com/TanStack/table/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/tanstack-table
