Introduction
A TypeScript-first tree and checkbox-tree component for React, built to look production-ready the moment you install it.
Most "tree view" packages on npm give you a bare hierarchy renderer and leave selection logic, keyboard navigation, and styling entirely up to you. TreeKit starts from a different premise: cascading checkbox selection, indeterminate state, keyboard accessibility, and a polished default appearance are not optional extras — they're the reason you reach for a tree component library instead of writing your own.
Drop in <TreeKit data={data} /> and you get a fully interactive, accessible tree. Reach for the same component's escape hatches — renderNode, CSS custom properties, the headless useTree hook — when you need more control than the defaults give you.
Show code
import { TreeKit } from "@treekit-ui/core";
import "@treekit-ui/core/styles.css";
<TreeKit data={data} defaultExpandedIds={["engineering"]} />What TreeKit gives you
- Correct checkbox semantics. Real
<input type="checkbox">elements with the nativeindeterminateproperty — not a styled div simulating one. - Configurable cascading. Choose whether checking a parent checks its children, whether checking children updates the parent, both, or neither.
- Controlled or uncontrolled.
expandedIds,checkedIds, andselectedIdsall support both patterns. - Real accessibility. WAI-ARIA tree semantics, roving tabindex, full keyboard navigation — verified with automated
jest-axechecks, not just added as an afterthought. - A styling system, not a stylesheet to fight. Every visual property is a CSS custom property. Override what you need; leave the rest.
- Search, async loading, and custom rendering as first-class, documented features — see the Features section.
Design philosophy
TreeKit separates tree math from rendering. Cascading selection, indeterminate computation, and visible-node flattening are all pure functions exported from the package and fully unit tested — the React layer is a thin consumer of that logic. This is also why useTree, the hook powering <TreeKit />, is itself part of the public API: if the default rendering doesn't fit your use case, you can build your own on the same engine instead of forking the library.