Virtual Scrolling
Render thousands of rows with constant memory usage. Only visible rows plus a configurable overscan buffer are mounted — the rest is pure CSS translateY.
Virtual Scrolling
Render thousands of rows with constant memory usage. Only visible rows plus a configurable overscan buffer are mounted — the rest is pure CSS translateY.
Compound API
Declarative compound component API. Compose Header, Column, Body, Row, Cell, and more with a clean, composable interface.
Suspense Caching
useTableCache integrates with React Suspense for initial loads and handles paginated fetching, sort-aware mutations, and real-time upserts out of the box.
Column Persistence
Users can resize columns by dragging. useTableColumnWidths persists widths to localStorage and supports both pixel and fractional (fr) values.
import { VirtualTable, useTableCache } from '@requence/table'
function Users() { const cache = useTableCache('users', { pageSize: 50, getItemId: (u) => u.id, compare: (a, b) => a.name.localeCompare(b.name), fetchItems: async (offset, limit) => { const res = await fetch(`/api/users?offset=${offset}&limit=${limit}`) return res.json() }, })
return ( <VirtualTable totalCount={cache.totalCount} rowHeight={32} onRangeChange={cache.handleRangeChange} > <VirtualTable.Header> <VirtualTable.Column width="2fr">Name</VirtualTable.Column> <VirtualTable.Column width="2fr">Email</VirtualTable.Column> <VirtualTable.Column width={100}>Role</VirtualTable.Column> </VirtualTable.Header>
<VirtualTable.Body> {(index) => { const user = cache.getItem(index) if (!user) return null return ( <VirtualTable.Row> <VirtualTable.Cell>{user.name}</VirtualTable.Cell> <VirtualTable.Cell>{user.email}</VirtualTable.Cell> <VirtualTable.Cell>{user.role}</VirtualTable.Cell> </VirtualTable.Row> ) }} </VirtualTable.Body>
<VirtualTable.Empty>No users found.</VirtualTable.Empty>
<VirtualTable.Footer> {({ start, end }) => `Rows ${start + 1}–${end}`} </VirtualTable.Footer> </VirtualTable> )}npm install @requence/table