The primary hook — covers pagination, sorting, filtering, selection, expansion, grouping, pinning, persistence, and URL sync in one call.
The single hook that covers most use cases. Every option is optional; the
returned table is a full TanStack Table instance with every feature bound.
Because TanStack Table v9 types a table as Table<TFeatures, TData>, tablecraft
exports the alias TablecraftTable<TData> — the instance type with tablecraft's
feature set already filled in. Use it wherever you need to name the type:
import type { TablecraftTable } from '@marvinackerman/tablecraft'function Toolbar({ table }: { table: TablecraftTable<User> }) { /* … */ }
{ pageSize?, pageIndex? }, or true (defaults), or false (disabled)
manualPagination
boolean
Server-driven pagination — pair with rowCount
rowCount
number
Total row count, used with manualPagination
onPaginationChange
OnChangeFn<PaginationState>
Custom pagination change handler
sorting
SortingOptions | boolean
{ defaultSort? }, or true, or false
manualSorting
boolean
Server-driven sorting
onSortingChange
OnChangeFn<SortingState>
Custom sorting change handler
globalFilter
boolean
Enable global text filter
onGlobalFilterChange
(value: string) => void
Custom global filter handler
columnFilters
boolean
Enable per-column filters
onColumnFiltersChange
OnChangeFn<ColumnFiltersState>
Custom column filter handler
rowSelection
RowSelectionOptions | boolean
true, or { defaultSelection?: RowSelectionState, enableMultiRowSelection? }
columnVisibility
ColumnVisibilityOptions | boolean
true, or { defaultVisibility? }
rowExpansion
RowExpansionOptions | boolean
true, or { defaultExpanded?, allowMultiple?, paginateExpandedRows?, getSubRows? }
grouping
GroupingOptions | boolean
true, or { defaultGrouping?, manualGrouping?, groupedColumnMode? }
columnPinning
ColumnPinningOptions | boolean
true, or { defaultPinning? }
columnOrder
ColumnOrderOptions | boolean
true, or { defaultOrder? }
rowPinning
RowPinningOptions | boolean
true, or { defaultPinning? }
columnResizing
ColumnResizingOptions | boolean
true, or { defaultSizing?, mode?, direction? } — mode defaults to 'onEnd'
fuzzy
boolean | FilterFn<TablecraftFeatures, TData>
true loads match-sorter via require() — CJS/Node only. In ESM-only bundlers (Vite, browsers) import fuzzyFilterFn from @marvinackerman/tablecraft/fuzzy and pass that — see below.
fuzzy: true reaches match-sorter through require(), which throws in
ESM-only bundlers. The /fuzzy entry imports it the normal way, so it works
everywhere — and consumers who never use fuzzy search do not carry the code:
import { useTable } from '@marvinackerman/tablecraft'import { fuzzyFilterFn } from '@marvinackerman/tablecraft/fuzzy'useTable({ data, columns, globalFilter: true, fuzzy: fuzzyFilterFn })
match-sorter is an optional peer: install it only if you use this.
An empty order (the default) is TanStack's sentinel for natural order, so
moveColumn is a no-op until you seed columnOrder: { defaultOrder: [...] }
— e.g. table.getAllLeafColumns().map(c => c.id). No drag-and-drop UI is
provided; wire moveColumn to a drag library like
dnd-kit or to plain buttons — see
useColumnOrderState for the
reasoning.
Remove a column's override, falling back to its columnDef size
resetAll
() => void
Clear all overrides
getSize
(columnId: string) => number | undefined
Committed width, or undefined if unset
This slice is the committed widths only — the state half of resizing. Its
type is ColumnSizingReturn, not ColumnResizingReturn — the two names are
easy to conflate. ColumnResizingReturn is the return type of the separate
hook, useColumnResizing(table), which
builds the drag handles that write into this slice; it needs the table
instance rather than options and so isn't returned from useTable itself. If
you hit a TS2322 between these two near-identical names, useTable().columnResizing
is ColumnSizingReturn and useColumnResizing(table)'s return is
ColumnResizingReturn.
position: sticky for pinned columns is plain CSS — tablecraft only provides state and the pixel offsets (column.getStart('start'), column.getAfter('end')). No UI lock-in.
columnOrder, rowPinning and columnResizing are available on useServerTable (it delegates straight to useTable) and on useQueryTable (its return type extends useTable's) with the identical option shape. useInfiniteTable does not get any of the three — its return type is standalone rather than extending useTable's, so nothing forced these three onto it, and they were left out of scope deliberately rather than by oversight.
See Persistence & URL sync for persist* / syncUrl details, and State hooks if you're composing useReactTable yourself instead of using useTable.