Tablecraft
API Reference

useTable

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<TData> instance.

Signature

function useTable<TData extends RowData>(
  options: UseTableOptions<TData>
): UseTableReturn<TData>

Options

OptionTypeDescription
dataTData[]Row data (required)
columnsColumnDef<TData, any>[]Column definitions (required)
paginationPaginationOptions | boolean{ pageSize?, pageIndex? }, or true (defaults), or false (disabled)
manualPaginationbooleanServer-driven pagination — pair with rowCount
rowCountnumberTotal row count, used with manualPagination
onPaginationChangeOnChangeFn<PaginationState>Custom pagination change handler
sortingSortingOptions | boolean{ defaultSort? }, or true, or false
manualSortingbooleanServer-driven sorting
onSortingChangeOnChangeFn<SortingState>Custom sorting change handler
globalFilterbooleanEnable global text filter
onGlobalFilterChange(value: string) => voidCustom global filter handler
columnFiltersbooleanEnable per-column filters
onColumnFiltersChangeOnChangeFn<ColumnFiltersState>Custom column filter handler
rowSelectionRowSelectionOptions | booleantrue, or { defaultSelection?: RowSelectionState, enableMultiRowSelection? }
columnVisibilityColumnVisibilityOptions | booleantrue, or { defaultVisibility? }
rowExpansionRowExpansionOptions | booleantrue, or { defaultExpanded?, allowMultiple?, paginateExpandedRows?, getSubRows? }
groupingGroupingOptions | booleantrue, or { defaultGrouping?, manualGrouping?, groupedColumnMode? }
columnPinningColumnPinningOptions | booleantrue, or { defaultPinning? }
fuzzyboolean | FilterFn<TData>true loads match-sorter via require() — CJS/Node only. In ESM-only bundlers (Vite, browsers), pass a FilterFn directly instead.
persist'localStorage' | 'sessionStorage' | falsePersist state across reloads — see Persistence & URL sync
persistKeystringStorage key — required when persist is set
persistOptionsPersistOptionsWhich state slices to persist
syncUrlboolean | URLSyncOptionsSync state to the URL — see Persistence & URL sync

Usage

import { useTable } from '@marvinackerman/tablecraft'

const {
  table,          // Full TanStack Table<TData> instance
  pagination,
  sorting,
  globalFilter,
  columnFilters,
  rowSelection,
  columnVisibility,
  rowExpansion,
  grouping,
  columnPinning,
  emptyState,
} = useTable({
  data,
  columns,
  pagination: { pageSize: 20 },
  sorting: { defaultSort: [{ id: 'name', desc: false }] },
  globalFilter: true,
  columnFilters: true,
  rowSelection: true,
  columnVisibility: { defaultVisibility: { email: false } },
  rowExpansion: { getSubRows: (row) => row.children },
  grouping: { defaultGrouping: ['role'] },
  fuzzy: true,
  persist: 'localStorage',
  persistKey: 'my-table',
  persistOptions: { sorting: true, pagination: true },
  syncUrl: true,
})

Return

pagination

PropertyTypeDescription
pageIndexnumberCurrent page (0-indexed)
pageSizenumberRows per page
pageCountnumberTotal pages
canPreviousPagebooleanCan go back
canNextPagebooleanCan go forward
previousPage() => voidGo to previous page
nextPage() => voidGo to next page
setPageIndex(index: number) => voidJump to page
setPageSize(size: number) => voidChange page size

sorting

PropertyTypeDescription
sortingStateSortingStateCurrent sort state
setSortingOnChangeFn<SortingState>Set sort state directly
clearSorting() => voidClear all sorting

globalFilter

PropertyTypeDescription
valuestringCurrent search string
setValue(val: string) => voidSet the search string
clear() => voidClear the search string

columnFilters

PropertyTypeDescription
stateColumnFiltersStateCurrent per-column filter values
setFilter(columnId, value) => voidSet a single column's filter
clearFilter(columnId) => voidClear one column's filter
clearAll() => voidClear all column filters

rowSelection

PropertyTypeDescription
stateRowSelectionStateCurrent selection map
toggleRow(rowId: string) => voidToggle a row
toggleAll() => voidSelect / deselect all
clearSelection() => voidClear all
selectedRowIdsstring[]IDs of selected rows
selectedCountnumberNumber selected
isSelected(rowId: string) => booleanCheck if selected

columnVisibility

PropertyTypeDescription
stateVisibilityStateCurrent visibility map
toggleColumn(columnId: string) => voidToggle a column
showColumn(columnId: string) => voidShow a column
hideColumn(columnId: string) => voidHide a column
showAll() => voidShow every column
hiddenColumnsstring[]Currently hidden column IDs

rowExpansion

PropertyTypeDescription
stateExpandedStateCurrent expanded rows
toggleRow(rowId: string) => voidToggle expand
expandRow(rowId: string) => voidExpand a row
collapseRow(rowId: string) => voidCollapse a row
clearExpansion() => voidCollapse all
expandedRowIdsstring[]IDs of expanded rows
isExpanded(rowId: string) => booleanCheck if expanded

grouping

PropertyTypeDescription
stateGroupingStateCurrent grouped columns
toggleGrouping(columnId: string) => voidToggle group by column
setGrouping(cols: GroupingState) => voidSet grouping directly
clearGrouping() => voidRemove all grouping
isGrouped(columnId: string) => booleanCheck if grouped
groupedColumnsstring[]Currently grouped column IDs

columnPinning

PropertyTypeDescription
stateColumnPinningStateRaw TanStack pinning state
pinLeft(columnId: string) => voidPin column to left edge
pinRight(columnId: string) => voidPin column to right edge
unpin(columnId: string) => voidRemove pin from column
clearPinning() => voidUnpin all columns
isPinned(columnId: string) => 'left' | 'right' | falseQuery pin status
leftColumnsstring[]Currently left-pinned column IDs
rightColumnsstring[]Currently right-pinned column IDs

emptyState

PropertyTypeDescription
isEmptybooleantrue when data has 0 rows total
isFilteredEmptybooleantrue when data exists but filters return 0 rows

Notes

  • position: sticky for pinned columns is plain CSS — tablecraft only provides state and the pixel offsets (column.getStart('left'), column.getAfter('right')). No UI lock-in.
  • columnPinning is also available on useQueryTable and useInfiniteTable with the identical option shape.
  • See Persistence & URL sync for persist* / syncUrl details, and State hooks if you're composing useReactTable yourself instead of using useTable.

On this page