关于 design-to-code
design-to-code 通过四阶段流水线,将截图、URL 或文字描述转为 React 组件。它会先检查现有组件和项目规范;具备依赖时,还可将输出注册到 json-render 目录。
主要功能
- 01从输入中提取设计细节
- 02优先匹配现有组件
- 03适配项目令牌与规范
- 04生成带类型的 React 组件和测试
- 05将组件注册到 json-render 目录
- 06通过 Storybook MCP 验证组件
适用场景
- 01将截图转换为 React 组件
- 02根据网页 URL 构建组件
- 03复用项目或 Storybook 组件
- 04准备组件以供多界面渲染
MCP 相关
该技能可使用 Stitch MCP 提取屏幕细节,并通过 Storybook MCP 查找和测试组件。它会检测 MCP 工具是否可用;不可用时可改用文件系统搜索或手动分析继续执行。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill design-to-code安装后在 Claude Code 中输入/design-to-code确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
test-cases.jsonrules/_sections.mdcatalog-registration.md详细介绍
设计转代码
使用四阶段流水线将视觉设计转换为可用于生产环境的 React 组件:提取、匹配、适配、渲染。
design-to-code screenshot of hero section # From description
design-to-code /tmp/mockup.png # From screenshot
design-to-code https://example.com/pricing # From URL
流水线概览
Input (screenshot/description/URL)
│
▼
┌─────────────────────────┐
│ Stage 1: EXTRACT │ Stitch MCP → screen details + URLs
│ generate_screen_from_text│ Create screens from a text prompt
│ get_screen │ Screen details with download URLs
└─────────┬───────────────┘
│
▼
┌─────────────────────────┐
│ 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
└─────────────────────────┘
参数解析
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
步骤 0:检测输入类型和项目上下文
# 1. Create main task IMMEDIATELY
TaskCreate(subject="Design to code: {INPUT}", description="Four-stage pipeline: extract, match, adapt, render", activeForm="Converting design to code")
# 2. Create subtasks for each stage
TaskCreate(subject="Extract design context", activeForm="Extracting design context") # id=2
TaskCreate(subject="Match components (Storybook-first)", activeForm="Matching components") # id=3
TaskCreate(subject="Adapt to project tokens and conventions", activeForm="Adapting to project") # id=4
TaskCreate(subject="Register in json-render catalog", activeForm="Registering in catalog") # id=5
TaskCreate(subject="Verify with Storybook self-healing", activeForm="Verifying component") # id=6
# 3. Set dependencies for sequential stages
TaskUpdate(taskId="3", addBlockedBy=["2"]) # Match needs extracted design context
TaskUpdate(taskId="4", addBlockedBy=["3"]) # Adapt needs matched components
TaskUpdate(taskId="5", addBlockedBy=["4"]) # Render needs adapted component
TaskUpdate(taskId="6", addBlockedBy=["5"]) # Verify needs rendered component
# 4. Update status as you progress
TaskUpdate(taskId="2", status="in_progress") # When starting
TaskUpdate(taskId="2", status="completed") # When done — repeat for each subtask
# Detect project's design system
Grep("@theme", glob="**/*.css") # Tailwind v4: theme lives in CSS, not a config file
Glob("**/tailwind.config.*") # Tailwind v3 only (v4 ignores this file)
Glob("**/tokens.css")
Glob("**/.tokens.json")
# Read existing tokens if found → used in Stage 3
# Detect shadcn/ui style (v4 style system)
Glob("**/components.json")
# Read → style field (e.g., "radix-luma", "base-nova")
# Determines class names: Luma=rounded-4xl, Nova=compact, Lyra=sharp
# Store: SHADCN_STYLE for Stage 2 filtering + Stage 3 adaptation
阶段 1:提取设计上下文
如果 stitch MCP 可用:
# Live Stitch MCP tools (https://stitch.googleapis.com/mcp), matching
# design-context-extractor / design-system-architect agent grants:
# - list_projects() / get_project(projectId)
# - list_screens(projectId)
# - get_screen(name="projects/{projectId}/screens/{screenId}")
# ONE required param: name. Returns screen details including
# download URLs (fetch those URLs; no separate code/image export tool)
# - generate_screen_from_text(projectId, prompt)
# quota-costing write; can take a few minutes. DO NOT RETRY.
# On timeout: poll get_screen(name=...) every 30 s, up to 10 times.
#
# For screenshot/URL input:
# 1. list_projects / get_project to locate the Stitch project
# 2. generate_screen_from_text with the extraction goal (or use an
# existing screen if the project already has one). Never retry.
# 3. list_screens, then get_screen(name="projects/{projectId}/screens/{screenId}")
# 4. Fetch the download URLs (or Read multimodal) for token extraction
#
# For description input:
# 1. generate_screen_from_text(projectId, prompt=<description>) once
# 2. On timeout, poll get_screen(name=...) every 30 s up to 10 times
# 3. Otherwise get_screen(name="projects/{projectId}/screens/{screenId}")
#
# DESIGN.md import (Stitch Pro, Mar 2026+):
# Prefer upload_design_md / create_design_system_from_design_md when
# those tools are available on the live server; otherwise regenerate
# via generate_screen_from_text from the DESIGN.md contents (once, no retry).
如果 stitch MCP 不可用(回退方案):
# 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
分辨率预算(Opus 5.5 / CC 2.1.111+): 长边不超过 2,576 px(约 3.75 MP,是之前上限的 3 倍)的模型图可更好地提取组件边界和间距。现在,原生分辨率的整页桌面模型图也在预算范围内;以前必须缩小尺寸,导致精细细节丢失。仅缩小超过 2,576 px 的输入图像。
提取并生成:
- 调色板(hex/oklch 值)
- 字体排版(字体系列、字号、字重)
- 间距模式(内边距、外边距、间隙)
- 组件结构(页眉、卡片、按钮等)
- 布局模式(grid、flex、侧边栏等)
阶段 2:匹配组件(优先使用 Storybook)
优先级 1 — 检查项目自己的 Storybook(如果 storybook-mcp 可用):
# Search the project's existing component library first
inventory = list-all-documentation() # Full component + docs manifest
for 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
优先级 2 — 搜索 21st.dev(如果未匹配到 Storybook 且 21st-dev-magic 可用):
# 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)
优先级 3 — 文件系统回退方案(如果没有 MCP 服务可用):
# 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
向用户展示匹配结果:
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
}])
阶段 3:适配项目
将提取的设计上下文与匹配或生成的组件合并:
- 应用项目 Token — 将硬编码的颜色和间距替换为项目的设计 Token
- 应用 shadcn 样式类 — 如果检测到
SHADCN_STYLE,使用符合样式的类名:- Luma:按钮和卡片使用
rounded-4xl、shadow-md+ring-1 ring-foreground/5、gap-6 py-6 - Nova:紧凑的
px-2 py-1、缩小外边距、紧凑间距 - Lyra:
rounded-none、锐利边缘、适合等宽字体 - Mira:超紧凑、最小内边距
- Luma:按钮和卡片使用
- 遵循命名约定 — 遵循项目的组件命名模式
- 添加 TypeScript 类型 — 提供完整类型安全,并使用 Zod 验证任何数据属性
- 包含测试 — 对由 API 支持的组件使用 MSW 处理程序,对静态组件进行渲染测试
- 响应式 — 采用移动优先设计,断点与项目系统保持一致
输出结构
src/components/
└── {ComponentName}/
├── {ComponentName}.tsx # Main component
├── {ComponentName}.test.tsx # Tests
└── index.ts # Barrel export
阶段 4:注册到 json-render 目录
ADAPT 生成可用的 React 组件后,将其注册为 json-render 目录条目,以便在多个界面中复用。
- 生成 Zod schema — 根据组件的 TypeScript 属性推导 Zod schema
- 添加目录条目 — 在项目的
defineCatalog()调用中注册,并提供属性 schema 和子项声明 - 验证渲染 — 确认组件可通过
<Render catalog={catalog} />路径正确渲染
import { z } from 'zod'
// Zod schema derived from {ComponentName}Props
const componentSchema = z.object({
title: z.string().max(100),
variant: z.enum(['default', 'featured']).default('default'),
// ... props from the adapted component
})
// Add to project catalog
import { defineCatalog } from '@json-render/core'
import { existingCatalog } from './catalog'
export const catalog = {
...existingCatalog,
{ComponentName}: {
props: componentSchema,
children: true, // or false for leaf components
},
}
支持: 将同一组件输出用于 PDF、电子邮件、视频或 MCP 响应,无需重新实现。
跳过条件: 如果项目没有 json-render 依赖或目录,请告知用户并跳过目录注册。阶段 3 生成的组件仍可独立使用。
阶段 4b:自修复验证(如果 storybook-mcp 可用)
生成组件后,使用 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 attempts
if not 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
跳过条件: 如果 storybook-mcp 不可用,则跳过验证。组件仍可使用,只是不会自动验证。
优雅降级
| stitch | 21st-dev-magic | storybook-mcp | 行为 |
|---|---|---|---|
| 可用 | 可用 | 可用 | 完整流程:提取 + 优先匹配 Storybook + 适配 + 渲染 + 自愈验证 |
| 可用 | 可用 | 不可用 | 提取 + 匹配 21st.dev + 适配 + 渲染(不进行验证) |
| 可用 | 不可用 | 可用 | 提取 + 匹配 Storybook + 适配 + 验证 |
| 不可用 | 可用 | 可用 | 基于描述搜索 + 检查 Storybook + 适配 + 验证 |
| 不可用 | 不可用 | 可用 | 仅进行文件系统搜索 + Storybook 验证 |
| 不可用 | 不可用 | 不可用 | 手动分析 + 从头生成(仍可正常工作) |
无论 MCP 是否可用,此技能总会生成输出。Storybook MCP 可实现组件复用(阶段 2)和自愈验证(阶段 4b)——即使跳过这些步骤,仍能得到可用的组件。
反模式
- 绝不输出带有硬编码颜色的组件——请使用设计令牌
- 绝不跳过 TypeScript 类型——所有属性都必须有类型
- 绝不在检查现有项目模式前就开始生成
- 绝不忽视项目现有的组件库结构
质量标准
满足以下所有条件才算完成:
- 生成的组件不包含硬编码颜色或字面量间距——每个视觉值都通过项目设计令牌解析。
- 每个属性都有 TypeScript 类型;承载数据的属性还需进行 Zod 验证。
- 阶段 2 在从头生成前检查了现有组件(先查 Storybook,再查 21st.dev,最后查文件系统),并注明了所选匹配来源。
- storybook-mcp 可用时,组件在交付前通过
run-story-tests(组件 + 无障碍)测试,并在最多 3 次尝试内完成自愈。 - 输出遵循
{ComponentName}/结构——包含组件、测试和 barrel 导出。 - 仅当依赖项缺失时才跳过各阶段(json-render catalog、Storybook 验证),并说明跳过原因。
相关技能
storybook-mcp-integration— Storybook MCP 工具:组件发现、测试、预览component-search— 独立搜索 21st.dev 注册表design-context-extract— 从截图中提取设计 DNAdesign-stylecards— 用于生成组件润色阶段的命名美学配方(阴影堆栈、玻璃表面、渐变、字体比例)design-system-tokens— 令牌架构与管理storybook-testing— CSF3 模式、Vitest 集成、Chromatic TurboSnapjson-render-catalog— 目录定义、Zod 模式、defineCatalog 模式multi-surface-render— 将目录条目渲染为 PDF、电子邮件、视频、MCP