tldraw/tldraw
@tldraw/editor
Active contributors: Steve Ruiz, Mitja Bezenšek, Mime Čuvalo, David Sheldrick
Purpose
@tldraw/editor is the foundation of the SDK. It exports the Editor runtime, the ShapeUtil and BindingUtil base classes, the StateNode state-machine type for tools, the <TldrawEditor /> React component, and a set of managers that power input, snapping, history, viewport, and rendering. It does not ship any default shapes, tools, or UI — that's @tldraw/tldraw's job.
Directory layout
packages/editor/
├── api-report.api.md
├── editor.css
├── package.json
└── src/
├── index.ts # public exports (~500 lines)
└── lib/
├── TldrawEditor.tsx # the React component (21 KB)
├── components/ # default canvas, error boundary, SVG defs
├── config/ # createTLStore, defaults, current user
├── editor/
│ ├── Editor.ts # the Editor class (11.5k lines)
│ ├── managers/ # 15 managers
│ ├── shapes/ # ShapeUtil base
│ ├── bindings/ # BindingUtil base
│ ├── tools/ # StateNode base
│ ├── derivations/
│ ├── overlays/
│ ├── assets/
│ └── types/
├── primitives/ # Box, Vec, Mat, easings, intersect, geometry
├── hooks/ # React hooks the editor exposes
├── license/ # license-key validation
├── globals/ # global setup
├── utils/ # editor-internal helpers
├── options.ts # TLEditorOptions
├── watermarks.ts # SDK watermark rendering
└── version.tsKey abstractions
| Type | File | Purpose |
|---|---|---|
Editor |
packages/editor/src/lib/editor/Editor.ts |
The runtime API. Owns store, history, camera, managers, root state-node. |
<TldrawEditor /> |
packages/editor/src/lib/TldrawEditor.tsx |
The React component. Mounts the canvas and exposes the Editor via context. |
ShapeUtil<Shape> |
packages/editor/src/lib/editor/shapes/ShapeUtil.ts |
Base class for shape behavior (geometry, render, handles, hit-test, export). |
BindingUtil<Binding> |
packages/editor/src/lib/editor/bindings/BindingUtil.ts |
Base class for binding behavior. |
StateNode |
packages/editor/src/lib/editor/tools/StateNode.ts |
State-machine node. Tools are state nodes. |
HistoryManager |
packages/editor/src/lib/editor/managers/HistoryManager/ |
Undo/redo stack. |
SnapManager |
packages/editor/src/lib/editor/managers/SnapManager/ |
Shape-to-shape snapping while moving/resizing. |
SpatialIndexManager |
packages/editor/src/lib/editor/managers/SpatialIndexManager/ |
RBush-backed spatial index. |
InputsManager |
packages/editor/src/lib/editor/managers/InputsManager/ |
Pointer/keyboard event normalization. |
ClickManager |
packages/editor/src/lib/editor/managers/ClickManager/ |
Single/double/triple-click classification. |
TickManager |
packages/editor/src/lib/editor/managers/TickManager/ |
Per-frame tick. |
ThemeManager |
packages/editor/src/lib/editor/managers/ThemeManager/ |
Color theme resolution. |
Box, Vec, Mat |
packages/editor/src/lib/primitives/ |
Geometry primitives. See Primitives. |
How it works
The editor is constructed by <TldrawEditor /> (or directly via new Editor(...) in tests). It owns the store of records and a tree of StateNodes rooted at the root state. User input enters through the canvas's pointer/keyboard handlers, gets normalized by InputsManager and ClickManager, then dispatched into the current tool. Tools mutate the store via the editor's API (editor.createShape, editor.updateShape, …), and reactive derivations (e.g., editor.getCurrentPageShapes()) propagate to React.
graph LR
Component["<TldrawEditor />"] -->|construct| Editor
Editor -->|owns| Store
Editor -->|owns| Managers
Editor -->|root| StateNode
Component -->|render| Canvas
Canvas -->|input events| Editor
StateNode -->|via editor| Store
Store -->|reactive| ComponentThe 15 managers under packages/editor/src/lib/editor/managers/ are each focused subsystems:
| Manager | What it does |
|---|---|
ClickManager |
Classifies pointer up sequences as click/double/triple. |
CollaboratorsManager |
Tracks remote presence records. |
EdgeScrollManager |
Auto-scrolls the camera near the viewport edge. |
FocusManager |
Tracks editor focus to gate keyboard input. |
FontManager |
Loads and measures fonts. |
HistoryManager |
Push/pop undo entries; editor.run integrates with this. |
InputsManager |
Pointer, keyboard, wheel event handling and normalization. |
PerformanceManager |
Records perf traces during interactions. |
ScribbleManager |
Renders the temporary "scribble" feedback during tools like draw. |
SnapManager |
Computes snap candidates against shapes and gridlines. |
SpatialIndexManager |
Wraps rbush to answer "what's at this point/box?". |
TextManager |
Measures and lays out text. |
ThemeManager |
Selects a light/dark/custom theme. |
TickManager |
Drives per-frame logic. |
UserPreferencesManager |
Loads and persists user preferences. |
Integration points
- Imports.
@tldraw/store,@tldraw/tlschema,@tldraw/state,@tldraw/state-react,@tldraw/utils,@tldraw/validate. Plus@tiptap/*(rich text),idb(IndexedDB persistence),rbush(spatial index),eventemitter3,classnames. - Importers.
@tldraw/tldrawis the primary consumer.@tldraw/syncand theapps/dotcom/clientalso import the editor directly. - Public surface. Defined by
packages/editor/src/index.ts(~500 lines of exports). Re-exports the entirety of@tldraw/state,@tldraw/state-react,@tldraw/store,@tldraw/tlschema,@tldraw/utils,@tldraw/validate. Adds editor-specific types (Editor,TldrawEditor,ShapeUtil,BindingUtil,StateNode,Box,Vec,Mat, manager types, default components, hooks).
Entry points for modification
- Adding a manager? Add a folder under
packages/editor/src/lib/editor/managers/<Name>/, instantiate it inEditor(search for the existing manager fields like_history,_snaps). - Changing input behavior? Look at
packages/editor/src/lib/editor/managers/InputsManager/and the dispatch path inEditor.ts(search fordispatch,handlePointerDown). - Changing default canvas rendering?
packages/editor/src/lib/components/default-components/ships the swappable defaults. - Adding a public API? Edit
packages/editor/src/index.ts, add the implementation underlib/, document with@public, and runyarn build-apifrom the repo root.
Related
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.