Getting started
Install
Install the binding you want. Each one depends on the layers beneath it, so there is never a second package to remember.
npm install @klad/coreThere is a fourth package, @klad/engine, but you only install it directly to write a binding for a framework that does not have one. It is the pure-logic layer — layout, viewport maths, the quadtree, the renderer, the worker protocol — and it touches no DOM.
The smallest chart
data is the only option without a default. Give it a flat array and you have a working chart: nodes are sized 180x64, labelled from each item's name (or label, or title, or failing those its id), laid out top-to-bottom, pannable, zoomable and keyboard-navigable.
import { createKlad } from '@klad/core'
const chart = createKlad(document.getElementById('chart')!, {
data: [
{ id: 'ceo', name: 'Jamie Fox' },
{ id: 'cto', parentId: 'ceo', name: 'Amy Chen' },
{ id: 'cfo', parentId: 'ceo', name: 'Priya Rao' },
],
})The host element needs a height
The chart fills its host and follows it with a ResizeObserver. A host that collapses to zero height gives you a chart you cannot see — the single most common setup problem, and it looks exactly like "nothing rendered".
Shaping the data
data is a flat array. Parentage is parentId and nothing else — there is no nested children shape to convert to, which means the array that came back from your API is very often already the right shape.
;[
{ id: 'ceo' }, // no parentId -> a root
{ id: 'cto', parentId: 'ceo' },
{ id: 'lead', parentId: 'cto' },
]Everything beyond id and parentId is yours: name, title, avatarUrl, whatever your card renders and your label reads.
Several roots are fine — the layout places them side by side. A parentId naming an item that is not in the array does not throw; that item becomes a root and a warning event describes what happened, so a chart built from partial data still draws.
Then add what you need
Each of these is one option or one call, and none of them is a prerequisite for the others. Take them in whatever order your chart asks for.
| You want | Add |
|---|---|
| Your own card instead of a drawn label | renderNode, a #node slot, or a render prop — see Node content |
| Bigger or per-node boxes | nodeSize — see Sizing |
| A different growth direction | orientation: 'lr', plus rtl if you need mirrored siblings |
| To start collapsed | collapsedByDefault: true |
| A map of where you are | minimap: true |
| To react to clicks | chart.on('nodeClick', …) / @node-click / onNodeClick — see Events |
| To move the camera | chart.api.focus(id), fit(), zoomTo(k) — see Navigating |
| Different colours | theme, live via setTheme — see Theme |
A fuller example
The same chart with the options most charts end up wanting: real cards, a minimap, and a click handler.
import { createKlad } from '@klad/core'
const chart = createKlad(document.getElementById('chart')!, {
data,
nodeSize: { w: 220, h: 88 },
minimap: true,
renderNode: (element, { item }) => {
element.innerHTML = `<div class="card">
<strong>${item.name}</strong><small>${item.title ?? ''}</small>
</div>`
},
})
chart.on('nodeClick', ({ id, item }) => console.log('clicked', id, item))
// When the host element goes away:
chart.destroy()Next
- Node content — putting your own components on the nodes.
- Sizing — why
nodeSizeis declared, and what to do when a card changes height. - Navigating — going to a node, opening the way to it, showing the route.