Compare
No React tree library ships virtualization, tri-state checkboxes and your own markup in one package.
That sentence is the entire reason this library exists, and it is the only claim on this page that flatters it. The headless libraries hand virtualization back to you. The virtualized ones arrive with a design system or a licence key. This one covers that gap and loses several columns below doing it — no drag-and-drop, no async children, no checkable folders, and eight downloads a week against a competitor’s two million.
| Library | Virtualized | Tri-state | Headless | Keyboard + ARIA | Drag & drop | Async loading | Search | TypeScript | Free | gzip | Weekly |
|---|---|---|---|---|---|---|---|---|---|---|---|
| react-virtual-checkbox-tree this one | Yes | Yes. Folders derive state only — they can never be checked in their own right. | Yes | Yes | No. Explicit non-goal. No reordering, no inline rename, no context menu. | No. There is no onLoadChildren prop. You rebuild `data` and state survives. | Yes | Yes | Yes. MIT. | 12.6 kB | 8 |
| react-checkbox-tree | No. Every node renders. Issue #43 has been open since 2017. | Yes | Partial. You can swap icons and class names, but the row markup and CSS are the library's. | Partial. Space and Enter toggle a focused node. Arrow-key tree navigation is issue #24, open since 2017. | No | No | No. No filter prop in the props table. You filter the `nodes` array yourself. | Yes. Ships src/index.d.ts. The source is JavaScript with prop-types. | Yes | 11.0 kB | 61,054 |
| react-arborist | Yes. react-window under the hood, rowHeight prop. | No. No checkboxes at all. Tracking issue #352 is open. | Partial. You write the node component; the row, drag preview and drop cursor are replaceable. | Yes | Yes | Partial. No lazy-children API, but the tree is happy to be handed new data. | Yes | Yes | Yes | 30.8 kB | 433,646 |
| headless-tree | No. Its own docs: "Virtualization is not a included feature of Headless Tree." | Yes. checkboxesFeature with propagateCheckedState. | Yes | Yes | Yes. Pointer and keyboard drag-and-drop, both first class. | Yes | Yes | Yes | Yes | 13.5 kB | 296,920 |
| MUI X Rich Tree View (community) | No. Virtualization lives in RichTreeViewPro. | Yes. checkboxSelection + selectionPropagation, indeterminate handled automatically. | No. It is Material Design. That is the point of it. | Yes | No. Item reordering is a Pro feature. | No. Lazy loading is a Pro feature. | No. No filtering prop in the Tree View docs. | Yes | Yes. MIT, but the virtualized variant is not. | 21.2 kB | 1,043,769 |
| MUI X Rich Tree View Pro | Yes. On by default in v9, itemHeight defaults to 32px. | Yes | No | Yes | Yes | Yes | No | Yes | No. $299 per developer per year for MUI X Pro. | 40.8 kB | — |
| rc-tree / antd Tree | Partial. Only when you pass `height`. Without it NodeList returns the full list. | Yes. checkable, with checkStrictly to turn the cascade off. | No. Ant Design markup and class names, or rc-tree's unstyled-but-fixed structure. | Yes | Yes | Yes. loadData returns a promise and children arrive on expand. | Partial. filterTreeNode marks matching nodes. It does not remove the rest. | Yes | Yes | 27.4 kB | 2,223,750 |
Last verified 2026-09-10. Hover any half-filled cell for the caveat — every one of them has a caveat, including ours. Downloads are the npm registry’s own numbers for 2026-08-31 → 2026-09-06. Gzip figures are Bundlephobia’s for the exact published versions, and include each library’s dependencies — ours too, which is why this table says 12.6 kB where the rest of the site says 5.6 kB for the library on its own. Our figure comes from npm run size in the repo, so you can reproduce it rather than take it on trust.
How to read the columns
Virtualized
The DOM holds a window of rows, not every node. A tree that renders 100,000 rows is not virtualized however fast its diff is.
Tri-state
A parent whose children are partly checked reads indeterminate, and it stays correct at every depth — not just one level up.
Headless
You supply the markup. Shipping a stylesheet you must import, or a required design system, is not headless — it is themeable, which is a different promise.
Keyboard + ARIA
role="tree" with arrow keys, Home/End, type-ahead and correct aria-checked. Space-to-toggle alone is half a mark.
Async loading
A first-class hook for fetching children when a folder opens. Being able to hand the component new data is not the same thing, and it is scored as half.
Search
A query prop that changes which rows exist. Marking matches without removing non-matches is scored as half.
The columns this library loses
Two cells in the first row are empty, and two more losses are not columns at all. None of the four are oversights.
Drag & drop, rename, context menus
Explicit non-goals. This is a selection control, not a file manager. react-arborist and headless-tree both do this properly and you should use one of them if you need it.
Async children
There is no
onLoadChildrenprop. You can rebuilddataas pages arrive and nothing is lost, but that is a workaround, not a feature.Checkable folders
Folders derive their state and cannot hold one. “Grant the whole department” as a value distinct from “grant every current member” is not expressible. rc-tree’s
checkStrictlyand react-checkbox-tree’scheckModel="all"both give you this today.Install base and maturity
v0.2.0, a 0.x API that will move before 1.0, and eight downloads a week. rc-tree has 2.2 million. If “how many production apps have hit this bug before me” is your top question, the honest answer here is: almost none.
Read the long version
- react-checkbox-treeThe incumbent. Same mental model, no virtualization path.
- react-arboristVirtualized and excellent, but has no checkboxes.
- headless-treeSame philosophy, wider scope — and virtualization is your job.
- MUI X Rich Tree ViewVirtualization is behind the Pro licence.
- rc-tree / antd TreeGenuinely virtualized, if you want an Ant-shaped API.
- Writing it yourselfThe real competitor. The four bugs you will write.
Sources
- npm weekly downloads, 2026-08-31 → 2026-09-06
- Bundlephobia minified + gzipped
- react-checkbox-tree #43 — Poor performance when data is huge (open since 2017)
- react-checkbox-tree #24 — Allow greater keyboard control (open since 2017)
- react-arborist #352 — Tracking: Checkbox selection & indeterminate state (open)
- headless-tree — Virtualization recipe
- MUI X — Rich Tree View virtualization (Pro)
- MUI X pricing
- rc-tree NodeList.tsx — `if (virtual === false || !height)`
Something wrong, stale, or unfair? Open an issue and this table changes. Maintainers of the libraries above: corrections from you go in first, and a cell that should be green will be made green.