Stitch Design
AI-powered UI design with Google Stitch — generate, iterate, export.
Setup
Required: Node.js 18+ and STITCH_API_KEY env var.
Get a key at: https://stitch.withgoogle.com → Profile → API Keys
Configure the key in your OpenClaw skill env settings or in the shell used to run the CLI.
# Install dependencies (one-time, from skill root)
cd scripts && npm install
Install scope: this installs the Node dependency declared in scripts/package.json (@google/stitch-sdk) plus its npm transitive dependencies.
Troubleshooting:
STITCH_API_KEY not set → ensure the env var is configured in OpenClaw skill settings or shell
ECONNRESET / timeouts → Stitch API calls take 1-5 min; the CLI retries automatically
Corrupt names.json → run node scripts/stitch.mjs rebuild --project <id> to reconstruct from event log
Usage
Runtime Scope
- Network: Google Stitch API and Google-hosted screenshot URLs returned by Stitch
- Credentials:
STITCH_API_KEY only
- Local writes:
runs/, state/, latest-screen.json
- No extra services, daemons, browser automation, or unrelated credentials required
The CLI is at scripts/stitch.mjs. All output is JSON on stdout.
node scripts/stitch.mjs <command> [args] [--flags]
Workflow: New Design
Use when user wants to design something from scratch.
Step 1 — Shape the prompt (see references/prompt-guide.md for keywords)
Transform the user's brief into a richer prompt:
- Add layout terms (sidebar, card grid, hero section...)
- Add visual tone (minimal, dark mode, editorial...)
- Specify device explicitly
Step 2 — Generate
node scripts/stitch.mjs generate <project-id> "shaped prompt" --device desktop
Typical time: 1–5 minutes. The CLI downloads HTML + PNG automatically.
Step 3 — Preview
Show the hi-res screenshot: run show <alias> → display via MEDIA:<screenshotUrl> (see Image Delivery).
Step 4 — Iterate (edit or variants)
Workflow: Edit Design
Use when user wants targeted changes to an existing screen.
node scripts/stitch.mjs edit <screen-id> "change the header to blue, add a search bar"
# --project auto-detected from latest-screen.json
Focused edits work better than vague ones. Be specific: colors, layout, components.
Workflow: Design Variants
Use when user wants to explore directions before committing.
# 3 variants, exploring freely
node scripts/stitch.mjs variants <screen-id> "make it feel more premium" --count 3 --range explore
# More conservative: refine only
node scripts/stitch.mjs variants <screen-id> "tighten the spacing" --count 2 --range refine
# Target specific aspects
node scripts/stitch.mjs variants <screen-id> "new color direction" --aspects color_scheme,text_font
Creative ranges:
refine — small changes, stays close to original
explore — moderate exploration (default)
reimagine — radical redesign
Aspects (comma-separated): layout, color_scheme, images, text_font, text_content
Workflow: Visual Review (Browse & Pick)
Use when user wants to see existing designs and decide which to work on.
Step 1 — Get project overview
node scripts/stitch.mjs info <project-id>
This returns all screen IDs + titles.
Step 2 — Export screenshots for each screen
node scripts/stitch.mjs image <screen-id> --project <project-id>
Do this for each screen (or a selection). Each call saves a local thumbnail + result.json with the screenshotUrl.
Step 3 — Send images to user
For each screen: get the screenshotUrl from the image command's result.json, append =w780, and display via MEDIA:<url>.
Include screen ID + title as caption so user can reference them.
Step 4 — User picks a screen
User says "take screen 3" or "the dark one" → match to screen ID.
Step 5 — Continue with edit/variants
Use the picked screen ID for edit or variants workflows.
Workflow: Export
Download HTML + screenshot from an existing screen.
node scripts/stitch.mjs export <screen-id> --project <project-id>
# or just HTML:
node scripts/stitch.mjs html <screen-id>
# or just screenshot:
node scripts/stitch.mjs image <screen-id>
Multi-Screen Consistency
Rule: Always start with a Hub Screen
Related screens of a concept need a shared hub screen as their visual basis. Generate is generative — layout, colors, spacing, and typography are all invented from scratch. Edit takes the source screen as the visual basis and changes only what you describe — navigation, typography, and color palette stay consistent.
generate vs edit — the key difference:
generate = brand-new screen. Everything is up for grabs.
edit = visual continuation of the source screen. Only the described delta changes.
Recommended Workflow
- Generate the hub screen → review it carefully
- All further screens of the same concept →
edit from the hub, not fresh generate
- Max 1-2 changes per edit prompt — Stitch regenerates generatively, not surgically. Too many changes = unpredictable results
- Even elements you did NOT mention can change in an edit. Fewer changes = more stable output.
Core Rule: For multi-screen concepts, always define a hub screen first, then derive further screens via edit — never fresh generate.
Reduce to Core (Concept Phase)
During the concept phase, 3-4 consistent core screens are enough. Full screen coverage only after the concept is approved. Stitch excels at rapid exploration, not exhaustive elaboration.
Screen Review Loop
A systematic loop for deciding when to keep editing in Stitch vs. when to note something for post-export fixing.
4-Step Loop
Step 1 — Run generate or edit
Step 2 — Analyze the screenshot (vision model)
Check against this list:
- Layout structure — sections in right order, correct hierarchy
- Colors — matches design system / brief
- Content — no hallucinated labels, avatars, or copy that doesn't belong
- Navigation — correct tabs, back buttons, menu items
- Design System Compliance — spacing, typography, component patterns
Step 3 — Categorize issues
| Category | Examples |
|---|
| Stitch-fixable | Missing section, wrong layout order, major color error, wrong navigation structure |
| Post-Export Fix | Exact pixel spacing, icon details, typography fine-tuning, persistent content hallucinations (avatars, labels) |
Step 4 — Decide
- Fix in Stitch → write a focused edit prompt (max 1-2 changes), go back to Step 1
- Post-export fix → note it, move on to next screen
Decision Tree
- Stitch didn't fix it after 2 edits → note as post-export fix, move on
- Detail work (shadows, exact radii, pixel spacing) → directly note as post-export fix, don't waste edit budget
- Structural issue (section missing, navigation wrong) → Stitch edit
The user decides which external tool to use for post-export fixes — Figma, Framer, code, or any other tool. Do not prescribe a tool.
Planning — Feature Coverage
Before generating anything, create a feature matrix: which features appear on which screen. Only start generating once the coverage is clear. This way every subsequent generate/edit call is a deliberate execution step, not a discovery — no surprises, no forgotten features. Keep this matrix short; a simple table or bullet list per screen is enough. Three focused screens you've thought through are worth more than ten screens you discover issues with during generation.
Project Management
# List all projects
node scripts/stitch.mjs projects
# Create a new project
node scripts/stitch.mjs create "App Name"
# Show project screens
node scripts/stitch.mjs info <project-id>
State Tracking
latest-screen.json (in skill root) tracks the last generated/edited screen.
edit, variants, html, image, export auto-detect project from latest-screen.json
- Override with
--project <id> when needed
Screen Names (Alias Registry)
Screens get auto-generated IDs like bcde81e368e24edbabd6213d9dc17b3b. Use screen names to give them memorable aliases that persist across sessions.
Naming screens
# Name during generation (recommended — naming in the flow)
node scripts/stitch.mjs generate <project-id> "prompt" --name concept-a
# Name during editing (alias follows the new screen)
node scripts/stitch.mjs edit <screen-id> "changes" --name concept-a --force
# Name an existing screen manually
node scripts/stitch.mjs name concept-a <screen-id> --project <id>
# Add a note
node scripts/stitch.mjs name concept-a <screen-id> --note "Karte als Fenster, Bottom Sheet"
Looking up screens
# Show screen details via alias or screen ID (fetches live data from Stitch API)
node scripts/stitch.mjs show concept-a
node scripts/stitch.mjs show bcde81e368e24edbabd6213d9dc17b3b
# Resolve alias to screen ID only
node scripts/stitch.mjs resolve concept-a
# List all named screens in a project
node scripts/stitch.mjs names
# List + verify against Stitch API (checks for deleted screens)
node scripts/stitch.mjs names --verify
Managing names
# Rename
node scripts/stitch.mjs rename concept-a map-startscreen
# Remove
node scripts/stitch.mjs unname old-concept
Naming rules
- Slugs only: lowercase
a-z, 0-9, hyphens. Case-insensitive.
- Examples:
concept-a, home-v2, onboarding-flow, dark-variant-3
- Not allowed: spaces, uppercase, special characters
- Aliases are unique per project — the same alias can exist in different projects
- Use
--force to overwrite an existing alias
How it works
- Names are stored in
state/projects/<projectId>/names.json (rebuildable snapshot)
- Every operation is recorded in
state/projects/<projectId>/events.jsonl (append-only, immutable)
- The Stitch API remains the source of truth for screen data — local state only stores mappings and history
- If a screen is deleted in Stitch,
show will report it as broken; names --verify checks all at once
- If
names.json gets corrupted, run rebuild to reconstruct from the event log (pre-log aliases require a backup or manual re-naming)
Event Log & History
Every generate/edit/variants operation and every alias change is recorded as an append-only event.
# Show all events for an alias (creates, edits, rebinds)
node scripts/stitch.mjs history concept-b
# Show a specific alias revision (Nth time it was bound to a screen)
node scripts/stitch.mjs history concept-b --rev 2
# Walk the edit/variant lineage DAG backwards from a screen
node scripts/stitch.mjs lineage concept-b
node scripts/stitch.mjs lineage abc123def456
# Rebuild names.json from event log (recovery)
node scripts/stitch.mjs rebuild --project <id>
Event types:
generate / edit / variants — screen operations (with parentScreenId, promptPreview, runDir)
alias_set / alias_renamed / alias_removed — alias pointer changes
- Variants include a
variantGroupId to group related screens
Agent workflow (MANDATORY)
When generating or editing screens for the user:
- Always use
--name when the user has a clear concept name or purpose for the screen
- If the user refers to a screen by name (e.g. "show me Concept A"), use
show <alias> first
- When editing a named screen, use
--name <same-alias> --force to keep the alias pointing to the latest version
- After every generate/edit/variants: run
show <alias|screenId>, extract screenshotUrl, display via MEDIA:<url> (see Image Delivery section)
- Use
names at session start to see what screens already exist
Artifacts
Every operation saves to runs/<YYYYMMDD-HHmmss>-<operation>-<slug>/:
| File | Content |
|---|
screen.html | Full HTML/CSS/JS of the screen |
screen.png | Screenshot (desktop/mobile) |
result.json | Metadata (screenId, projectId, prompt, timestamps) |
variant-N.html/.png | For variants commands |
Architecture
The skill uses a 3-layer local state model. The Stitch API is always the source of truth for screen content (HTML, screenshots).
| Layer | Storage | Purpose |
|---|
| Artifacts | runs/<timestamp>/ | Immutable per-operation receipts: thumbnail, HTML, result.json |
| Event Log | state/projects/<id>/events.jsonl | Append-only chronological record of all operations |
| Alias Pointers | state/projects/<id>/names.json | Current named references — rebuildable from event log |
Key principles:
runs/ are artifacts (never mutated, never deleted)
state/ is the mutable layer (names.json is a snapshot, events.jsonl is append-only)
names.json can be rebuilt from events.jsonl via rebuild (complete for all alias changes recorded in the log; pre-log aliases are preserved from existing snapshot if available)
- Local thumbnails (
screen.png) are low-res; always use screenshotUrl + =w780 for display
state/ and runs/ are gitignored — they are local working state, not source code
Core Rules
- MANDATORY: Read
references/prompt-guide.md before your first generate/edit/variants call in a session. It contains critical prompting principles that determine output quality. For SDK details (methods, types, enums), see references/sdk-api.md.
- Always shape prompts — Never pass the user's raw text directly to Stitch. Enrich it using the Prompt Framework (Context → Structure → Aesthetic → Constraints) from the prompt guide. Transform weak prompts into strong ones.
- Component isolation by default — When the user asks for a component (not a full page), always add: "Design a single standalone UI component — do NOT generate a full application screen. Show it isolated on a neutral background."
- Preview first — Show the hi-res screenshot to user before offering export
- Visual feedback (MANDATORY) — After every generate/edit/variants, display the hi-res screenshot inline via
show <alias|screenId> → MEDIA:<screenshotUrl>. See "Image Delivery" section.
- Iteration > perfection — Follow the Anchor → Inject → Tune → Fix loop. Define what must NOT change in every edit prompt.
- One prompt = one thing — Never combine multiple components or screens in one prompt.
- Default values:
generate defaults to --device desktop. --model uses SDK default (pro). Explicit: --count 3, --range explore. edit and variants inherit device from the source screen.
- State awareness — Before asking the user for screen or project IDs, ALWAYS read
latest-screen.json first. If it has a recent entry, use that projectId/screenId. Only ask if no state exists or the user explicitly switches context.
- Figma export — Manual: open Stitch UI → "Copy to Figma" → paste in Figma. CLI can export HTML which also pastes into Figma
- Hub-first for multi-screen concepts — For multi-screen concepts, always define a hub screen first, then derive further screens via edit — never fresh generate.
Image Delivery (MANDATORY after every generate/edit/variants)
The local screen.png in runs/ is only a low-res thumbnail (~168×512px). Full-resolution images come from the Stitch API via screenshotUrl.
How it works
The show command accepts an alias OR a raw screen ID and returns live API data with a hi-res screenshot URL (=w780 suffix appended):
# By alias
node scripts/stitch.mjs show concept-a
# By screen ID (no alias needed)
node scripts/stitch.mjs show bcde81e368e24edbabd6213d9dc17b3b
# → { "screenshotUrl": "https://lh3.googleusercontent.com/...=w780", ... }
Agent workflow for image display
After every generate/edit/variants:
- With alias (preferred): run
show <alias> → extract screenshotUrl from JSON → MEDIA:<url>
- Without alias: run
show <screenId> (accepts raw screen IDs too) → same flow
- Last resort: get
screenshotUrl from runs/<dir>/result.json, append =w780, display via MEDIA:<url>
MEDIA:https://lh3.googleusercontent.com/...=w780
URL size suffixes
Google's lh3.googleusercontent.com URLs support size parameters:
=w780 — full mobile design width (default from show)
=w1440 — full desktop design width
=s2000 — max 2000px on longest side
- No suffix → thumbnail only (~168px wide)
Sketch-to-Design Workflow
Stitch interprets hand-drawn sketches and wireframes well. The SDK has no image upload — but the workflow is:
- User uploads sketch in Stitch Web UI (stitch.withgoogle.com)
- User tells the agent: "I uploaded a sketch called [title]" (or just "the sketch I just uploaded")
- Agent runs
info <project-id> → finds the screen by title in list_screens
- Agent uses
edit or variants on that screen to refine it
Limitations
- No image upload via SDK — Sketches/screenshots must be uploaded in Stitch Web UI first, then refined via the skill
- Models:
pro (Gemini 3.1 Pro) and flash (Gemini 3.0 Flash). "Redesign/NanoBanana" from the Web UI = variants --range reimagine
- Full-screen bias — Stitch defaults to generating complete layouts. Must be explicitly overridden for component work (see Core Rules).
- Content hallucination — Stitch adds unrequested copy, labels, badges. Always have the user review generated content.
- Long operations — generate/edit/variants take 1-5 minutes. Connection drops are handled automatically via recovery polling (generate/edit retry via
list_screens newest; variants use delta-based recovery by comparing screen lists before and after the call)
Flags Reference
| Flag | Commands | Values | Default |
|---|
--device | generate, edit, variants | desktop, mobile, tablet, agnostic | desktop for generate; inherited from source for edit/variants |
--model | generate, edit, variants | pro, flash | SDK default (pro) |
--count | variants | 1–5 | 3 |
--range | variants | refine, explore, reimagine | explore |
--aspects | variants | layout, color_scheme, images, text_font, text_content | all |
--project | all | project ID | from latest-screen.json |
--design-system | generate, edit, variants | design system name/slug | — |
Note on --design-system: Stitch supports native Design Systems (create_design_system), but the SDK does not yet allow linking them to generate/edit calls. --design-system is a workaround that loads design-systems/<name>.md from this skill folder and appends that content to your prompt. It does not accept arbitrary file paths. Once the SDK supports design_system_id in generate/edit, this flag will become obsolete.