Getting started

Prototype how you like

Every screen on the Statecraft canvas is live — real components rendering against real styles. The canvas is the default editing surface; you can also drop into source in your IDE or prompt an AI agent against the same project. Pick whichever fits the moment.

Three ways to edit

Statecraft doesn't pick a single editing surface for you. The canvas, your IDE, and your agent are equivalent gateways to the same project — use them in the same session if you want:

  • Visually on the canvas — the default for designers. Click an element to select it; the Properties panel exposes the props your design system declares (variant, size, colour token, copy). Drag and drop reorders elements inside a frame and across frames. See Editing states and Selecting & arranging elements for the visual surface in depth.
  • Source-first in your IDE — every state lands on disk as a plain .jsx or .vue file when you sync the workspace locally. Edit in VS Code, Cursor, or Zed and saves bounce back to the canvas. Details below.
  • By prompting an agent — Claude Code, Cursor, Codex, and most CLI agents work straight against the sync folder. Details below; deep reference at Build alongside an AI agent.

Everyone editing sees changes live, no matter the surface. A designer dragging an element, an engineer editing source, and an agent applying a refinement all show up on each other's canvas within a second.

States are screens, transitions are clicks

Whichever surface you're editing in, the shape of a prototype is the same: each screen is a state, each click is a transition, and the buttons you click are real components, not images of them.

Idle  ── submit ──▶  Success

That's the whole shape. Add more states (loading, error, empty) and more transitions between them, and you have the prototype your designer would sketch in Figma — except every click runs against production components.

Add a second state

The sidebar lists every state in the project. Click + Add state to create a new one. Statecraft seeds each new state with the same JSX as the one you had selected, so you can edit it incrementally rather than starting from a blank frame.

add-state-sidebar.png

Rename the state to something the rest of the team will recognise — success, loading, cart-empty. State names appear in transitions and in the Play URL, so they're worth picking deliberately.

Wire a transition

A transition has three pieces: the element you click, the event name, and the destination state. To connect a button on screen A to screen B from the canvas:

  1. On screen A, click the button to select it. In the Properties panel, set Transition to a name — submit works for most cases.
  2. In the sidebar's Transitions section, add a new transition: from screen A, on submit, to screen B.
  3. Click the Play button in the top-right toolbar. Play opens in a new browser window — click the button and the canvas advances to screen B.
properties-transition-field.png

Try it

Click the Play button in the toolbar to open the prototype in its own window. Every state is reachable; clicking any element with a transition on it advances to the destination state. Close the window when you're done to keep editing.

play-mode-clickable.png

Play URLs are shareable as-is — send one to a stakeholder and they see the same click-through experience, no editor chrome, no sign-in. See Share with users and colleagues.

Common shapes

  • Two-step form. idle submitsuccess. The simplest flow, and the one most onboarding tutorials end up modelling.
  • Multiple destinations from one screen. A login screen with login, signup, and forgot-password transitions, each pointing at a different state. Add three transitions from the same screen, one per element.
  • Self-loops. A retry button in an error state that transitions back to loading — same source and destination state isn't allowed, but you can transition back to whatever started the flow.
  • Branching on outcome. One loading state with two outgoing transitions: resolvedsuccess and rejectederror. Click whichever element represents the outcome you want to demo.

Want to show the same flow under different inputs? Build the happy path once with transitions, then duplicate the project and tweak the JSX for the unhappy path. Each copy is its own prototype with its own snapshot history, so you can A/B them in feedback rounds without one overwriting the other.

What's next

Once the click-through works, show every state of the feature so a reviewer can see loading, empty, and error — not just the happy path. To send it out, see Share with users and colleagues. The deeper reference for the underlying model is in States & transitions.

Editing source in your IDE

Turn on workspace sync from the desktop tray, point it at a folder on your machine, and Statecraft mirrors every project in the workspace to disk. Layout:

<sync-folder>/<workspace>/
  <project-slug>/
    project.json              # project metadata
    transitions.json          # source/destination/event triples
    _status.md                # last render verdict from the canvas
    states/
      _order.json             # state order + display names
      idle.jsx                # one file per state
      submit.jsx
      success.jsx
    canvas/                   # off-graph scratch states (see below)
      _order.json
      sketch-1.jsx

Edit any states/<name>.jsx file in VS Code, Cursor, or Zed. Saves round-trip back to the canvas in seconds via the same yjs sync that powers multiplayer — no manual push, no commit step. The canvas re-renders the state as soon as the file changes.

To mint a new state from your IDE, drop a new file into <project>/states/. The file name (a kebab-case slug) becomes the state's id; the daemon mints a Title-Case display name from the slug and adds a row to states/_order.json. To delete a state, delete the file.

To rename a state's display name or reorder states, edit states/_order.json directly. The slug (the filename) stays as the state's identity — that's what transitions point at — so renaming the file would break any transition referencing it. The display name and the canvas order both live in _order.json.

Hand-authoring transitions

Behind every transition the canvas creates is a data-transition attribute on the JSX of the clickable element:

<Button data-transition="submit">Place order</Button>

Plus a matching row in transitions.json declaring the source state, the event name, and the destination state. Either surface is editable directly — you can hand-author the attribute and the JSON row and the canvas picks it up next render, or use the canvas UI and let it write both for you.

Prompting an agent

The sync folder carries an AGENTS.md file at its root that Claude Code, Cursor, Codex, and most other CLI agents auto-load as their working context. Open the folder in your agent of choice, prompt in plain English, and it edits the same files your IDE would — within seconds, the canvas re-renders.

Examples:

  • "Add an empty state to the cart project — same layout as idle, but with a 'No items yet' message and a CTA back to the catalog."
  • "Make the error layout match the loading one — right now the header disappears when we move from loading to error and that's jarring."
  • "Wire a transition from every state in this project back to idle on a Cancel button."

The synced folder uses the same multiplayer machinery as the canvas, so concurrent edits from you, a teammate, and an agent don't clobber each other. See Build alongside an AI agent for the deep reference: CLI verbs, the AGENTS.md contract, agent-loop status checks.

Canvas drafts: off-graph scratch space

The canvas/ subfolder under each project holds floating sketches — JSX files that don't belong to any state and don't appear in Play mode, but render on the canvas next to the state frames. Drop a sketch-anything.jsx in there and the canvas mounts it as a draggable element you can iterate on without committing it to the prototype's state graph.

Useful when you want to ask an agent for three button variants and pick one to fold into the real state later, without polluting your state list with throwaway work.