Headless
The engine without the markup: every feature, none of the table. Use it for cards, lists, charts, or a table you draw yourself.
Basics
Loading example…
The features live in a core that knows nothing about the DOM. useDataTable gives you that core
as a React hook, and what you render is entirely yours:
const table = useDataTable({ data, columns, getRowId: (p) => p.id });
return (
<ul>
{table.getRowModel().rows.map((row) => (
<li key={row.id}>{row.getValue('name')}</li>
))}
</ul>
);
Sorting, filtering, search, pagination, grouping, selection and faceting all work; they are
computations over rows, not decorations on a table element. Only the rendering is missing,
because you are supplying it.
When this is the right shape
A list of cards with a sort control. A chart that has to honour the same filters as the table beside it. A virtualized feed. A table whose markup is dictated by a design system that will not accept a component. In all of them the hard part is the data pipeline, and that is exactly what this gives you.
Outside React
createTable is the same engine as a plain object, with subscribe for change notification. It
has no React dependency, which makes it usable in a test, a worker, or another framework's
adapter.
Meeting in the middle
You do not have to choose all or nothing. DataTable.Root plus the composable parts renders the
library's markup where you want it and yours everywhere else; see
Toolbar. useVirtualRows, useBreakpoint and useSyncState are all
exported for the same reason.
Customization
There is nothing to customize here; that is the point. What the styled table exposes as slots and handlers, the headless form exposes as ordinary function calls on the instance.
Limitations
- Accessibility becomes yours. The roles,
aria-sort, the live-region announcements and the keyboard model are in the rendering layer you are replacing. - The stylesheet is not involved, so tokens and presets do nothing until you use them.
flexRenderneeds table context. In a headless tree, readcell.getValue()and apply the column'sformatyourself rather than rendering cell contexts outside the table.
API
- Hooks:
useDataTable,useDataSource,useTableState,useVirtualRows,useBreakpoint,useSyncState. - Utilities:
createTable,createColumnHelper,createLocalDataSource,createRestDataSource. TableInstance: everything the engine exposes.