VirtualTable
A headless virtualized table hook built on TanStack Table + TanStack Virtual. Render thousands of rows with ease.
Basic Usage
ID
Name
Email
Department
Salary
1,000 rows
The simplest usage — just pass data and columns:
const { table, rows, virtualItems, totalSize, containerRef } = useVirtualTable({
data,
columns,
estimatedRowHeight: 44,
});| Option | Type | Default |
|---|---|---|
data | TData[] | required |
columns | ColumnDef<TData>[] | required |
estimatedRowHeight | number | 40 |
overscan | number | 5 |
getRowId | (row) => string | — |
Features
Explore each feature on its own page:
Sorting
Single & multi-column sorting
Row Selection
Checkbox-based row selection
Row Expansion
Expandable rows with detail views
Keyboard Navigation
Arrow keys, Home/End, Space/Enter
Infinite Scroll
Load more data on scroll
Column Resizing
Drag column borders to resize
Column Reordering
Drag and drop column reordering
Return Values
const {
// Core
table, // TanStack Table instance
rows, // Processed row models
virtualizer, // TanStack Virtual instance
virtualItems, // Currently visible virtual items
totalSize, // Total scrollable height (px)
containerRef, // Ref for scroll container
// Handlers
handleScroll, // For infinite scroll
handleKeyDown, // For keyboard navigation
reorderColumn, // (fromId, toId) => void
setFocusedRow, // (index) => void
// State (controlled or internal)
rowSelection, sorting, expanded, columnSizing, columnOrder, focusedRowIndex,
} = useVirtualTable(options);
Controlled vs Uncontrolled
Uncontrolled
State managed internally:
const { sorting } = useVirtualTable({
enableSorting: true,
});
// `sorting` reflects internal stateControlled
You own the state:
const [sorting, setSorting] = useState([]);
useVirtualTable({
enableSorting: true,
sorting,
onSortingChange: setSorting,
});