Tree JSON

  • data: {10 keys}
    • artist: "Joni Mitchell"
    • tour: "Blue, Revisited"
    • year: 2026
    • onSale: true
    • support: null
    • manager: {3 keys}
      • name: "Elliot Roberts"
      • email: "hello@beste.co"
      • phone: "+1 310 555 0142"
    • dates: [4 items]
    • setlist: [12 items]
      • 0: "All I Want"
      • 1: "My Old Man"
      • 2: "Little Green"
      • 3: "Carey"
      • 4: "Blue"
      • 5: "California"
      • Show 6 more (6 left)
    • band: [3 items]
    • rider: {2 keys}
      • piano: "Steinway D"

About this component

Tree JSON

A JSON viewer on the tree family's pattern: objects and arrays open and close with a height animation and a spring on the chevron, closed ones show a preview like {3 keys} or [12 items], and values are colored by type with strings, numbers, booleans and null each told apart in light and dark themes. Long arrays arrive in chunks behind a Show more row, a search field highlights matching keys and values, opens their parents and reaches into chunked arrays, and every row copies its value or its path, written the way you would in code (data.dates[2].city). Values stay selectable. The whole viewer is a WAI-ARIA tree: arrow keys walk it, Right and Left open, close and climb, `*` opens every sibling, and Cmd or Ctrl + C copies the focused value (with Shift, its path).

Usage

The import and the props worth knowing about, in one place.

import { TreeJson } from "@/components/beste/component/tree-json";

<TreeJson data={response} rootName="response" expandDepth={2} searchable />

// Controlled search and expansion, copy callback
<TreeJson
  data={config}
  rootName="config"
  expanded={open}
  onExpandedChange={setOpen}
  search={query}
  onSearchChange={setQuery}
  chunkSize={50}                 // array items shown at a time
  onCopy={(text, what, path) => console.log("Copied", what, path)}
  tone="outline"                 // "ghost" (default) | "muted" | "outline"
  size="sm"                      // "sm" | "default" | "lg"
/>

Keyboard and gestures

Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.

Arrow Up / DownMove between visible rows; the tree is one tab stop.
Arrow RightOpen a closed object or array, or step into an open one.
Arrow LeftClose an open object or array, or climb to the parent.
Home / EndJump to the first or last visible row.
Enter / SpaceOpen or close the row, or show the next chunk on a Show more row.
*Open every object and array at the focused row's level.
Cmd or Ctrl + CCopy the focused row's value; with Shift, its path.
Arrow Down in the searchJump to the first match.

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
data*unknown—Any JSON value: an object, an array or a single value.
rootNamestring—Name of the root, and the start of every copied path.
expandDepthnumber—Levels open on first render; 1 opens only the root.
expandedstring[]—Open paths, controlled. Paths look like `data.tours[2].city`.
defaultExpandedstring[]—
onExpandedChange(paths: string[]) => void—
searchableboolean—A search field above the tree that highlights matches and opens their parents.
searchstring—The search text, controlled.
defaultSearchstring—
onSearchChange(search: string) => void—
chunkSizenumber—Array items shown at a time; the rest wait behind a "Show more" row.
copyableboolean—Copy value and copy path buttons on each row.
onCopy(text: string, what: "value" | "path", path: string) => void—
tone"muted" | "outline" | "ghost"—
size"sm" | "default" | "lg"—
classNamestring—
aria-labelstring—

More Tree components

View all Tree
  • app
    • layout.tsx
    • page.tsx
    • tour
      • page.tsx
      • dates.json
  • .env
  • package.json
  • README.md