Astra
All docs

Concepts

Design spaces

A canvas where the agent builds mockups as live React frames you can look at, click through, and iterate on before any of it becomes real code.

A design tab is a canvas for visual work. Ask for a mockup and the agent builds it as live frames — real, running React you can look at and interact with, not a picture of an interface.

It’s for the stage before implementation: exploring what a screen should look like, putting variants side by side, and agreeing on a direction. Building a design changes no application code, so you can throw away five explorations without touching the app.

Canvases and frames

Two levels, and both are just files:

  • A canvas is a folder under .astra/designs/ in the repo.
  • A frame is a .tsx file directly inside that folder.

Adding a file adds a frame; deleting one removes it; renaming the folder renames the canvas. There’s no hidden state — the canvas is the directory, and it’s committed with everything else, so a branch carries its own designs.

Every frame is a self-contained React component that default-exports itself and declares its own size:

export const frame = { width: 1440, height: 900 };

export default function Home() {
  return <div style={{ /* ... */ }}>…</div>;
}

Frames are deliberately fenced. They style inline, and they may only import react and relative paths inside .astra/designs/ — so a frame can share a helper with its neighbors, but it can’t reach into your application code. A mockup that quietly depended on your real component library wouldn’t be a mockup any more.

Size is the frame’s own business, declared in its file. Position is the canvas’s: Astra writes a canvas.json beside the frames when you drag things around, and a new frame with no entry places itself next to the last one.

Working on a canvas

Open a design tab from the new-tab menu (⌘T). The tab carries its own conversation, and its acting mode is Design — Build’s equivalent for frames.

The canvas picks up file changes at the end of each turn, so you watch the design land as the agent finishes rather than flickering through half-written states. Frames the agent wrote or edited also show up as cards in the chat, which makes the transcript readable after the fact.

You can @-mention a design from an ordinary chat too, so an agent working on code knows which mockup you’re talking about.

Clicking through a prototype

The canvas itself never goes live — a board of running apps is hard to think on. Instead, each frame’s label has a on hover that opens it in a dedicated interact overlay.

In there the frame fills the pane and you can actually use it: click, type, navigate. Media queries and text still evaluate at the frame’s declared viewport, so a 390px frame behaves like a phone regardless of how big the overlay is. A reload button resets the prototype’s state, and the agent editing the frame reloads it too.

The loop this is built around is short: click around, find what’s wrong, tell the agent, watch it change.

When a frame breaks

Each frame is compiled on its own. A frame with a syntax error, a missing size export, or a disallowed import renders that error in place — the other frames on the canvas keep working. You never lose the whole board to one bad file, and you never get a silent blank where a frame should be.

The designs hub

The hub browses every canvas in a project without spending a space on it, reading the project’s main checkout. Read one, then use Open in a new space when you want to actually work on it — that mints a fresh space each time, because a design isn’t a conversation and shouldn’t be stuck to one.

Designs on a branch surface inside the space that owns that branch, not in the hub.

Turning a design into code

That’s a separate job, and an explicit one. A design is a mockup; asking for the real implementation is a different request, usually in a different space. Keeping the two apart is what makes it cheap to explore.