esc
navigate select
Browse documentation

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.

Engineering
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 native indeterminate property — 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, and selectedIds all support both patterns.
  • Real accessibility. WAI-ARIA tree semantics, roving tabindex, full keyboard navigation — verified with automated jest-axe checks, 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.