Skip to content
AI•11 min read

Stitch CLI: Google Brings UI Design to the Terminal (and to Your Agent)

Google has introduced Stitch CLI, a command-line tool (@google/stitch) that brings Stitch's generative UI design to the terminal and to your coding agent. The official promise: "you can go from a blank folder to a live, interactive design on localhost in a couple of minutes". - Source: Stitch CLI Overview

It's not just a screen generator. The CLI covers three fronts: generating and editing screens, maintaining a design system agents can read (DESIGN.md), and connecting your real repository to prototype over your product. This is the full guide, condensed from the entire documentation.

Image: Google (Stitch)

Install and sign in

It requires Node.js 20 or later.

# terminal
npm install -g @google/stitch
stitch --version

If you'd rather not install it, run npx @google/stitch. To authenticate, a single Google OAuth login enables both your Canvas projects and your workspace workflows:

stitch login

In headless environments or CI there's no browser: set STITCH_API_KEY or save an API key in the global config (stitch config set apiKey "your_api_key" --global). You can check your session status with stitch status. - Source: Stitch CLI Overview

The /stitch skill: the CLI inside your agent

This is the most interesting piece of the launch. The CLI ships a bundled skill so your coding agent knows how to drive it for you:

stitch agent-skills add --user

It works with Claude Code, Cursor, Gemini CLI, and Antigravity. Once installed, you invoke /stitch inside the agent's chat to generate screens, extract and sync a DESIGN.md, or audit your running app:

/stitch Create a new Stitch project called "Checkout Redesign" and generate a clean desktop order summary screen.

Your first screen from the terminal

Everything /stitch does, you can also do by hand. You start by creating a project and pinning the directory so you never retype --project:

stitch create project --title "Checkout Redesign"
stitch config set project <project-id>

Then you generate a screen from a prompt:

stitch generate screen \
  --title "Order Summary" \
  --device DESKTOP \
  --prompt "A clean two-column checkout summary on warm paper (#FAF8F5) with itemized billing, shipping selector, and a primary payment button"

And to see the result: stitch serve spins up a local preview server and stitch open project opens the Canvas in your browser. - Source: Stitch CLI Overview

Variations and targeted edits

When you're exploring, ask for several options at once. stitch generate variants produces 1 to 5 variants and controls two axes:

  • Creative Range (--creative-range): REFINE for finer adjustments (font, spacing, color), EXPLORE or REIMAGINE for bigger swings.
  • Aspects (--aspects): LAYOUT, COLOR_SCHEME, IMAGES, TEXT_FONT, TEXT_CONTENT.
stitch generate variants \
  --screen <screen-id> \
  --count 3 \
  --creative-range EXPLORE \
  --aspects LAYOUT,COLOR_SCHEME \
  --prompt "Explore a compact high-density layout and a high-contrast dark theme"

Once you have a screen you like, switch from exploration to precision. The rule is one change at a time, specific:

stitch edit screen <screen-id> \
  --prompt "Replace the top KPI cards with a compact single-line horizontal ticker and add a date-range selector in the top-right header."

To pull the HTML into your project: stitch get screen <screen-id> --code --output ./screens/overview.html. - Source: Generate & Edit Screens

The real flow with your agent: anchor, frame, interact

The docs are explicit about why generic outputs come out generic: start from a blank prompt and you get a generic color palette. Their recommended flow has three beats.

1. Anchor with real artwork. First generate the image that lives inside your interface with Gemini 3 Pro Image (gemini-3-pro-image) in Google AI Studio, in a 1:1 ratio, asking it to fill the frame edge-to-edge. Then upload it to the project:

stitch upload screen ./hudson-album-art.png --title "Late Sun on the Hudson"

Passing that image's URL in the prompt makes Stitch embed it pixel for pixel instead of inventing a placeholder.

2. Frame the design on the first prompt. When you ask for "a whole app", the model fills every corner with status dots and fake badges. The doc's recipe is a four-beat prompt: [Canvas] (what goes in and what stays out), [Principles] (every element must earn its place), [Artwork] (your uploaded image), and content/[Playback] (the exact data).

3. Make it interactive on localhost. Because Stitch outputs real HTML, CSS, and JavaScript, you don't stop at a static layout. Start stitch serve and ask for interaction on the live DOM: clicking a track should swap the sleeve, the vinyl label color, and the scrub bar.

Image: Google (Iterate with Coding Agents)

DESIGN.md: the design system your agent can read

The strongest idea in the whole launch concerns identity. Your visual identity lives in a Figma file, a brand PDF, or a designer's head. None of those is readable by an agent. DESIGN.md changes that: it's a plain-text design system document that humans and agents can read, edit, and enforce.

The docs frame it as the project's "third file":

FileWho reads itWhat it defines
README.mdHumansWhat the project is
AGENTS.mdCoding agentsHow to build the project
DESIGN.mdDesign agentsHow it should look and feel

It's a living artifact, not a static config: the agent generates it, you refine it, and it gets re-applied to screens as you iterate. There are three paths to create one, from easiest to most precise: let the agent generate it from a vibe description, derive it from your branding (give it a URL or an image and it extracts palette, typography, and patterns), or write it by hand. - Source: DESIGN.md Overview

The DESIGN.md specification

A DESIGN.md has two layers: YAML front matter with tokens (the exact values the agent enforces) and a markdown body with the rationale. Tokens are normative; prose provides context.

---
version: alpha
name: Daylight Prestige
colors:
  primary: "#1A1C1E"
  secondary: "#6C7278"
  tertiary: "#B8422E"
typography:
  h1:
    fontFamily: Public Sans
    fontSize: 48px
    fontWeight: 600
    lineHeight: 1.1
rounded:
  sm: 4px
  md: 8px
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    rounded: "{rounded.md}"
    padding: 12px
---

Key points of the spec:

  • Token types: color (# + sRGB hex), dimension (48px, -0.02em), token reference ({colors.primary}), and typography (a composite object with fontFamily, fontSize, fontWeight, lineHeight, letterSpacing, fontFeature, fontVariation).
  • References: any token can point at another with {path.to.token}. Inside components, referencing composite values is allowed (for example {typography.label-md}).
  • Canonical section order: Overview (or Brand & Style), Colors, Typography, Layout, Elevation & Depth, Shapes, Components, Do's and Don'ts. You can omit the ones that don't apply and add your own domain sections.
  • Extensible by design: the spec calls itself "a foundation, not a prescription". An unknown section (## Iconography), an oddly named color, or an invalid spacing value are all accepted; the only fatal error is a duplicate section heading.
  • Recommended names: colors primary, secondary, tertiary, neutral, surface, on-surface, error; typography headline-*, body-*, label-*; radii none, sm, md, lg, xl, full.
  • Source: DESIGN.md Specification

Validate, compare, and export with @google/design.md

The spec has its own CLI, which validates against the format, catches broken references, checks WCAG contrast, and exports tokens. Everything returns structured JSON an agent can act on.

# lint: validates structure and runs 8 rules
npx @google/design.md lint DESIGN.md

# diff: which tokens changed between two versions and whether it regressed
npx @google/design.md diff DESIGN.md DESIGN-v2.md

# export: tokens to Tailwind or to DTCG (W3C Design Tokens)
npx @google/design.md export --format tailwind DESIGN.md
npx @google/design.md export --format dtcg DESIGN.md

The linter runs 8 rules:

RuleSeverityWhat it checks
broken-referrorReferences that don't resolve; unknown component sub-tokens
missing-primarywarningColors exist but no primary (the agent will invent one)
contrast-ratiowarningbackgroundColor/textColor pairs below WCAG AA (4.5:1)
orphaned-tokenswarningColors defined but never referenced by a component
missing-typographywarningColors exist but no typography
section-orderwarningSections out of canonical order
missing-sectionsinfospacing or rounded missing (agent defaults will apply)
token-summaryinfoToken count per section

It's also available as a TypeScript library (you get report.findings, report.summary, report.designSystem, report.tailwindConfig). - Source: Validate with the CLI and Linting Rules

Capture your real app

If you're redesigning an existing page, don't start from a blank canvas: bring your real UI up. Capture and upload are deliberately separate, so you can inspect on disk before sending anything.

# client-rendered app (React, Next.js, Vite, Vue) in headless Chrome
stitch capture browser --url "http://localhost:3000/checkout" --wait-for "#checkout-root" -o .stitch/checkout.html

# HTML served over HTTP or a static build
stitch capture port --port 5173 --route "/dashboard" -o .stitch/dashboard.html
stitch capture file ./dist/index.html -o .stitch/index.html

Passing -o writes two files: the normalized HTML and a 1280x800 verification screenshot.

Getting past a login without touching your code has three options, all clean:

  1. Sign in on the open tab and freeze it without reloading: stitch capture browser --page 1 -o .stitch/dashboard.html.
  2. Pass saved cookies and localStorage: --storage .stitch/storage.json.
  3. Run a sign-in script before the snapshot: --prepare .stitch/signin.js.

And when uploading, you mark the route as the canonical reference: stitch upload screen .stitch/checkout.html --route "/checkout" --title "Checkout". - Source: Capture Live Apps

Local design review

This is where the CLI becomes a design linter. It compares your running app against your DESIGN.md, and everything runs locally, with no cloud calls:

stitch capture browser --url "http://localhost:5173/dashboard" -o .stitch/captured-dom.html

Instead of vague advice, you get a prioritized list of findings anchored to your CSS selectors, screenshot regions, and DESIGN.md rules. The agent pauses so you can pick which fixes to apply first. Four key checks: color and surface tokens (did arbitrary grays sneak in?), typography and numerals, spatial rhythm (the 4px/8px grid), and visual restraint (did status dots or pills show up where plain text would be cleaner?). If the audit uncovers a layout problem, you upload the snapshot to the Canvas and try options before touching your app. - Source: Audit App UI

Workspaces: when design looks at your repository

Generating standalone screens is great for starting something new. To have Stitch understand your real app (routes, navigation, components), you connect the repo to a Workspace. First you enable the feature once:

stitch enable loop

This unlocks all workspace commands (workspace, priority, insight, solution, context, upload code, upload file, connect, github) and updates the /stitch skill with the codebase onboarding playbook. Then, in three steps:

stitch create workspace --title "Acme Web App"
stitch config set workspace <workspace-id>

stitch upload code .                 # uploads your working tree without installing a GitHub App
# or connect GitHub:
stitch github login && stitch github repos
stitch edit workspace <workspace-id> --add-repo https://github.com/<owner>/<repo>

stitch loop link --project <project-id>   # binds the Canvas to the workspace

If your team keeps context in other tools, stitch connect --list shows the integration and webhook catalog. - Source: Connect a Repository

Priorities and context

In a Workspace, a priority isn't a ticket ("change the button to blue"). It's a standing design goal that tells Stitch what kind of UX improvements to look for across all your routes. The CLI ships a ready-made template:

stitch create priority --template ui-prototyping

This does two things at once: it creates the priority with CREATE_SUGGESTIONS autonomy (Stitch continuously proposes insights, specs, and design prompts) and syncs three workspace skills (design-synthesis, insight-guidelines, assessment-guidelines) to steer the agents toward visual prototyping instead of generic code lints. You can tailor the objective with --objective:

stitch create priority --template ui-prototyping \
  --objective "Transform passive schedule and booking tables across /schedule and /venues into tactile, direct-manipulation surfaces."

The docs are clear on the criterion: aim for outcomes that span several routes, not one-line tasks. And to add context, you upload specs and notes: stitch upload file ./specs/checkout-prd.pdf or stitch create context --title "Checkout Flow Goals" --description "...". - Source: Priorities & Context

Prototypes from your codebase

With the repo connected and a priority active, Stitch analyzes your routes in the background to spot passive readouts, workflow bottlenecks, and layout opportunities. Initial synthesis takes around 15 minutes.

stitch find insights          # route-anchored opportunities
stitch get insight <insight-id>
stitch find solutions         # each insight produces one or more solutions
stitch get solution <solution-id>

Each solution is a complete spec: a domain metaphor, DESIGN.md rules, and a calibrated prompt anchored to your reference screen. Take that prompt and generate the prototype on the Canvas:

stitch generate screen \
  --title "Interactive Schedule Workbench" \
  --device DESKTOP \
  --prompt "<prompt from stitch get solution>"

The command reference (the essentials)

The CLI exposes resource verbs (find, get, create, edit, delete, generate, open, url) plus the Canvas, capture, and config commands. In total, 23 commands:

CategoryCommands
Resourcescreate, delete, edit, find, generate, get
Actions & Canvascapture, connect, open, serve, upload, url
Auth & configconfig, disable, enable, github, login, logout, privacy, status
Advancedagent-skills, api, mcp

Three useful details:

  • stitch url prints the canonical Canvas URL (the docs warn: "never guess URLs").
  • stitch mcp starts the CLI's MCP server (mcp start over stdio) or registers it in your editor (mcp install).
  • --model on edit/generate lets you choose between GEMINI_3_8_FLASH and GEMINI_3_5_FLASH_LITE.

Almost every command accepts the global flags: --json, --format, --workspace/-w, --project/-p, --debug, --trace (HTTP trace and cURL reproduction), --fields, --no-cache, and --dry-run on mutations. - Source: CLI Command Reference

Why it matters

Three readings of all this:

  1. DESIGN.md makes design versionable and machine-readable. It's the same move AGENTS.md made for code instructions, but for visual identity. Having a linter validate WCAG contrast and broken references in CI is a real category shift.
  2. Local-first by default. The design review runs without cloud calls, and the capture is yours on disk before you upload anything. For teams under data restrictions, that matters.
  3. The web × AI bridge. The CLI doesn't compete with your agent: it feeds it. With /stitch, MCP, and DESIGN.md, design enters the same flow where your code and tests already live.

Wrapping up

Stitch CLI is more than a screen generator: it's a bet that design should live where code lives, in plain text and with an agent able to read it. If you already use a coding agent, the first step is stitch agent-skills add --user and asking /stitch to extract a DESIGN.md from your current repo.

Original source: Stitch CLI Overview (official Google Stitch documentation).

Would you try DESIGN.md in your project, or do you see it as another config layer bound to drift out of sync? Tell me in the comments.


> More posts