Core overview
How the editor is put together — the bundle that is the source of truth, the store that holds state, the commands that mutate it, the timeline, and the event bus.
The Core layer is the SDK without any UI. Every editor surface — built-in or plugin-contributed — sits on top of these pieces:
| Concept | What it is |
|---|---|
| Project bundle | The serializable JSON shape that fully describes a project. The "save file." |
| Store | A single Zustand + Immer instance holding StudioState. The runtime source of truth. |
| Contexts | React contexts that expose the store, the config, the icon map, and the plugin registry to the tree. |
| Commands | Reversible mutations. Every undoable change is a Command pushed to a 100-entry history. |
| Timeline | Tracks, items, transitions, markers, regions, snap engine, invariants. |
| Events | A typed mitt bus for plugin and consumer communication. |
These pages document each one in depth. Skim the table below to pick a starting point.
Project bundle
Shape of ProjectBundle, schema versioning, createEmptyBundle, normalizeBundle, loadBundle/toBundle.
Store
The full StudioState shape and every action it exposes.
Context store
The React contexts the provider sets up and how to consume them.
Commands
Command pattern, executeCommand, undo/redo, batching, authoring custom commands.
Timeline
Track, TrackItem, the itemIdsByTrack index, snap engine, invariants, time utilities.
Events
Typed event bus, full event catalog, subscription patterns.
One end-to-end mental model
A user action flows through these pieces in order:
- The user clicks / drags / types in a UI surface.
- The surface calls a store action (e.g.
addItem,moveItem,updateItemProperties). - The action constructs a Command (
execute+undo) and callsexecuteCommand. executeCommandrunsexecute(draft)inside Immer, pushes the command to the undo stack, clears the redo stack, setsproject.isDirty = true.- The store emits a typed event on the event bus.
- React components subscribed via
useStudioStore(selector)re-render. - Plugin code listening on the event bus runs side effects (analytics, autosave, etc.).
- The user clicks Save → the provider's
onSave(bundle)runs → your backend persists the bundle.
Every page below is some slice of this flow. Read in the order above for a top-down tour, or jump to whichever piece you're working on.