React Tree Table

A plain data table flattens a hierarchy into a list; a tree view keeps the hierarchy but drops the columns. This keeps both — the right shape for anything that is a tree and has numbers on every row: a bundle breakdown, a budget, a file system, an org chart.

ModuleSizeGzip% of bundle
vendor
412 KB138 KB66%
react-dom
130 KB42 KB21%
motion
96 KB33 KB15%
charting
118 KB40 KB19%
lucide-react
68 KB23 KB11%
app
214 KB71 KB34%
docs/*
148 KB49 KB24%
components/site
66 KB22 KB11%

Expand a group to see its children — the hierarchy of a tree with the aligned columns of a table.

Installation

npx shadcn@latest add "http://localhost:3000/registry/tree-table.json"

Props

PropTypeDescription
nodesTreeNode<T>[]{ id, data, children? }
columnsTreeColumn<T>[]{ key, header, render, align?, tree? }
defaultExpandedDepthnumberExpand down to this depth initially

One column carries the tree

Mark a column tree: true and it renders the indentation and the expand/collapse control; every other column is a plain aligned cell. That separation is what lets the same component show a bundle's module tree with right-aligned size and gzip columns, or a budget's line items with a percentage — the hierarchy lives in one column, the metrics in the rest, and they never fight for space.

Rows are flattened on each render from the set of expanded nodes, so state is a single Set of ids rather than a flag per node — cheap, and impossible to get out of sync. Generic over your row type T, with a render per column, so it stays a table of your data, not a fixed schema. Parent rows read slightly heavier than leaves, so the shape of the tree is legible even before you expand anything.

New components every week

Get the week's new Kelvin UI components and templates in one short email. No spam, unsubscribe anytime.