Mockup-to-component pipeline using Google Stitch, 21st.dev, and Storybook MCP. Accepts a screenshot, a description, or a URL and produces production-ready React components, checking existing Storybook components before generating anything new. Use when implementing UI from a mockup or screenshot. To call the MCP tool surface on its own, with no design to convert, use storybook-mcp-integration.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Claude Code 2.1.220+. Optional: stitch (official Google Stitch), 21st-dev-magic, storybook-mcp (@storybook/addon-mcp) MCP servers.
description
Mockup-to-component pipeline using Google Stitch, 21st.dev, and Storybook MCP. Accepts a screenshot, a description, or a URL and produces production-ready React components, checking existing Storybook components before generating anything new. Use when implementing UI from a mockup or screenshot. To call the MCP tool surface on its own, with no design to convert, use storybook-mcp-integration.
{"keywords":["design to code","mockup to code","screenshot to component","convert design","implement ui from","build from mockup"],"examples":["convert this screenshot into a React component","implement the UI from this Figma mockup","build a component from this design"],"anti-triggers":["explore","assess","review","brainstorm","extract design"]}
Convert visual designs into production-ready React components using a four-stage pipeline: Extract, Match, Adapt, Render.
/ork:design-to-code screenshot of hero section # From description
/ork:design-to-code /tmp/mockup.png # From screenshot
/ork:design-to-code https://example.com/pricing # From URL
Pipeline Overview
Input (screenshot/description/URL)
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Stage 1: EXTRACT โ Stitch MCP โ HTML + design context
โ build_site โ Generate up to 5 screens from prompt
โ get_screen_code / _image โ Extract React/HTML + PNG for each
โโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Stage 2: MATCH โ 1. Storybook MCP โ check existing
โ Storybook-first lookup โ 2. 21st.dev โ search public registry
โ Then 21st.dev fallback โ 3. Filesystem โ grep codebase
โโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Stage 3: ADAPT โ Merge extracted design + matched
โ Apply project tokens โ components into final implementation
โ Customize to codebase โ Tests + types included
โโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Stage 4: RENDER โ Register as json-render catalog entry
โ Generate Zod schema โ Same component โ PDF, email, video
โ Add to defineCatalog() โ Multi-surface reuse via MCP output
โโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Stage 4b: VERIFY โ Storybook MCP โ self-healing loop
โ run-story-tests(a11y) โ Fix violations, retry (max 3)
โ preview-stories โ Embed live preview in chat
โโโโโโโโโโโโโโโโโโโโโโโโโโโ
Argument Resolution
INPUT = ""# Full argument string# Detect input type:# - Starts with "/" or "~" or contains ".png"/".jpg" โ screenshot file path# - Starts with "http" โ URL to screenshot or live page# - Otherwise โ natural language description
# Official Stitch MCP tools (stitch.withgoogle.com/docs/mcp):# - build_site(prompt) โ multi-screen app, up to 5 interconnected screens# - get_screen_code(screenId) โ returns React/HTML for a generated screen# - get_screen_image(screenId) โ returns PNG of a generated screen## For screenshot/URL input:# 1. Upload screenshot to Stitch (or pass URL)# 2. Call build_site() with the visual as context# 3. get_screen_code() to retrieve the React/HTML output## For description input:# 1. Call build_site(prompt=<description>)# 2. get_screen_code() / get_screen_image() to retrieve the result## DESIGN.md import (Stitch Pro, Mar 2026+):# Stitch can also import a natural-language DESIGN.md file to regenerate# a layout without starting from scratch. Useful for iterative edits.
If stitch MCP is NOT available (fallback):
# For screenshot: Read the image file directly (Claude is multimodal)# Analyze layout, colors, typography, spacing from the image# For URL: WebFetch the page, extract HTML structure# For description: Skip extraction, proceed to Stage 2 with description
Resolution budget (Opus 5 / CC 2.1.111+): Mockups up to 2,576 px on the long edge (~3.75 MP, 3ร prior ceiling) produce better component boundaries and spacing extraction. Full-page desktop mockups at native resolution are now in-budget; previously they had to be resized down and lost fine detail. Only downscale inputs exceeding 2,576 px.
Priority 1 โ Check project's own Storybook (if storybook-mcp available):
# Search the project's existing component library first
inventory = list-all-documentation() # Full component + docs manifestfor component in inventory.components:
if component matches extracted_description:
details = get-documentation(id=component.id)
# Returns: props schema, stories, usage patterns# โ Existing component found โ skip external search
Priority 2 โ Search 21st.dev (if no Storybook match and 21st-dev-magic available):
# Search 21st.dev for matching components# Use the component descriptions from Stage 1# Example: "animated pricing table with toggle"# Filter: React, Tailwind CSS, shadcn/ui compatible# If SHADCN_STYLE detected, prefer components matching style's visual language# (e.g., Luma โ rounded/pill-shaped, Nova โ compact/dense, Lyra โ sharp/boxy)
Priority 3 โ Filesystem fallback (if no MCP servers available):
# Search for components in the project's existing codebase
Grep(pattern="export.*function|export.*const", glob="**/*.tsx")
# Check for shadcn/ui components
Glob("**/components/ui/*.tsx")
# Generate from scratch if no matches found
Present matches to user:
AskUserQuestion(questions=[{
"question": "Which component approach for {component_name}?",
"header": "Component",
"options": [
{"label": "Reuse from Storybook", "description": "{existing_component} โ props: {prop_list}"},
{"label": "Use 21st.dev match", "description": "{matched_component_name} โ {match_score}% match"},
{"label": "Adapt from codebase", "description": "Modify existing {existing_component}"},
{"label": "Generate from scratch", "description": "Build new component from extracted design"}
],
"multiSelect": false
}])
Stage 3: Adapt to Project
Merge the extracted design context with matched/generated components:
After ADAPT produces a working React component, register it as a json-render catalog entry for multi-surface reuse.
Generate Zod schema โ Derive a Zod schema from the component's TypeScript props
Add catalog entry โ Register in the project's defineCatalog() call with props schema and children declaration
Verify rendering โ Confirm the component renders correctly through <Render catalog={catalog} /> path
import { z } from'zod'// Zod schema derived from {ComponentName}Propsconst componentSchema = z.object({
title: z.string().max(100),
variant: z.enum(['default', 'featured']).default('default'),
// ... props from the adapted component
})
// Add to project catalogimport { defineCatalog } from'@json-render/core'import { existingCatalog } from'./catalog'exportconst catalog = {
...existingCatalog,
{ComponentName}: {
props: componentSchema,
children: true, // or false for leaf components
},
}
Enables: same component output to PDF, email, video, or MCP response โ no reimplementation needed.
Skip condition: If the project has no json-render dependency or catalog, inform the user and skip catalog registration. The component from Stage 3 is still fully usable standalone.
After generating the component, verify it with Storybook MCP:
# 1. Write CSF3 story for the new component
Write("src/components/{Name}/{Name}.stories.tsx", story_code)
# 2. Run tests via MCP (component + a11y)
results = run-story-tests(
stories=[{ "storyId": "{name}--default" }],
a11y=True
)
# 3. Handle failures โ self-heal up to 3 attemptsifnot results.all_passed:
for failure in results.failures:
# Read violation details, fix the component
Edit("src/components/{Name}/{Name}.tsx", fix)
# Re-run failing tests
results = run-story-tests(stories=[...], a11y=True)
# 4. Preview โ embed live story in chat for user confirmation
previews = preview-stories(stories=[
{ "absoluteStoryPath": "src/components/{Name}/{Name}.stories.tsx",
"exportName": "Default" }
])
# Include preview URLs in response for visual confirmation
Skip condition: If storybook-mcp is not available, skip verification. The component is still usable โ just not auto-verified.
Graceful Degradation
stitch
21st-dev-magic
storybook-mcp
Behavior
Available
Available
Available
Full pipeline: extract + Storybook-first match + adapt + render + self-heal verify
Available
Available
Unavailable
Extract + 21st.dev match + adapt + render (no verification)
Manual analysis + generate from scratch (still works)
The skill ALWAYS produces output regardless of MCP availability. Storybook MCP adds component reuse (Stage 2) and self-healing verification (Stage 4b) โ skipping them still yields a working component.
Anti-Patterns
NEVER output components with hardcoded colors โ use design tokens
NEVER skip TypeScript types โ all props must be typed
NEVER generate without checking existing project patterns first
NEVER ignore the project's existing component library structure
Quality Bar
Done means all of these hold:
Generated components carry no hardcoded colors or literal spacing โ every visual value resolves through project design tokens.
Every prop is TypeScript-typed; data-bearing props carry Zod validation.
Stage 2 checked existing components (Storybook, then 21st.dev, then filesystem) before generating from scratch, and the chosen match source is named.
When storybook-mcp is available, the component passes run-story-tests (component + a11y) before handoff, self-healing within at most 3 attempts.
Output follows the {ComponentName}/ structure โ component, test, and barrel export.
Each skipped stage (json-render catalog, Storybook verify) is taken ONLY when its dependency is absent, and the skip is stated with its reason.