Virtualisation out of the box
48,000 rows render like 12: only what is in the viewport is in the DOM. Switches on by itself once there are more than two hundred rows.
v2.4 · a headless table for React
Sorting, grouping, virtualisation and types — without a single style. tabl gives you the data and the behaviour, you draw the markup.
npm i tabl$ // playground
Every toggle is one option in code. On the left — what you write, on the right — what you get.
sort: { by: "size" } — one line, and the column is sorted. Stable, with any comparator.
groupBy: "type" — rows gather under headings with a count. Totals are computed for you.
view.zebra — even rows are tinted, a long table is easier to read.
density: "compact" — a third more rows in the same viewport. Still your markup.
import { useTable } from "tabl"
const table = useTable({
data,
columns: ["name", "type", "size", "updated"],
})
return <Table {...table.props} />| name | type | size, kb | updated |
|---|---|---|---|
| invoice-0412.pdf | 412 | today | |
| logo.svg | image | 18 | yesterday |
| report-q3.xlsx | sheet | 1290 | 3 days |
| cover.webp | image | 240 | a week |
| contract.pdf | 980 | a month | |
| budget.xlsx | sheet | 2100 | a month |
// features
Six things you usually write yourself and then fix. Here they are written once.
48,000 rows render like 12: only what is in the viewport is in the DOM. Switches on by itself once there are more than two hundred rows.
By any column, with a custom comparator and a stable order.
Not a single style inside. Light, dark, branded — the table picks up any of them.
Columns know the cell type: the editor will hint, TypeScript will check.
One key — and rows gather into collapsible groups with totals.
Smaller than an icon. Tree-shaking: you take only what you use.
// comparison
Gzipped size of headless tables for React. Data from bundlephobia on the day of the 2.4 release.
gzip, minimal import
Measured with `import { useTable }` and no styles. The full tabl feature set — 6.8 KB.
// community
Every pull request is reviewed by two maintainers, every release passes 1,900 tests. Join in — there is always a good first issue.
// version history
Semantic versions, breaking changes are marked. The full list is in CHANGELOG.md.
Full changelog →GitHub stars are the only metric by which a project gets into curated lists and finds people. If tabl saved you an evening — give a minute back.