/figma2design
Turn a Figma design link into a complete design system extraction — producing a .design/ directory with structured markdown specs, brand assets, and screenshots, ready for AI-driven UI generation.
Usage
/figma2design <figma-url> # full extraction
/figma2design <figma-url> --pages home,skills # extract specific pages only
/figma2design <figma-url> --screenshots-only # only screenshots, no docs
/figma2design <figma-url> --update # re-extract, keep existing files as reference
URL formats supported:
https://www.figma.com/design/:fileKey/:fileName?node-id=:int1-:int2https://figma.com/design/:fileKey/:fileNamehttps://www.figma.com/file/:fileKey/:fileName?node-id=:int1-:int2
What This Skill Produces
Given a Figma design file, this skill generates:
.design/
├── DESIGN.md # Design tokens (colors, typography, spacing, shapes, components)
├── CODE_PATTERNS.md # Tech stack + code conventions + layout patterns
├── COMPONENTS.md # Component behavior specs (props, states, interactions)
├── PAGES.md # Page-level specs (layout, data flow, interactions, states)
├── ICONS.md # Icon inventory with sources and sizes
├── brand/ # Brand assets extracted from Figma
│ ├── logo-mark.svg # Logo / brand mark
│ ├── app-icon.png # App icon
│ ├── mascot.png # Mascot / character (if present)
│ └── ...
├── icons/ # Custom icon SVGs extracted from Figma
│ ├── icon-name.svg
│ └── ...
└── screenshots/ # All key screens as PNG (named after Figma frames)
├── index.md # 截图目录:按功能模块分组,文件名 ↔ 说明
├── 首页.png
├── 技能库.png
└── ...
Each file answers a different question for the UI generator:
| File | Question it answers |
|---|---|
| DESIGN.md | What colors, fonts, spacing, and shapes? |
| CODE_PATTERNS.md | What tech stack? How to organize code? |
| COMPONENTS.md | What props does this component take? What states? |
| PAGES.md | What components go where? What data flows? |
| ICONS.md | What icon is that? Where to import it from? |
| brand/ | What are the actual logo/app-icon/mascot files? |
| icons/ | What custom SVG icons does the design use? |
| screenshots/ | What should it look like? (visual fallback + index) |
Prerequisites
- Figma MCP plugin (
figma@claude-plugins-official) installed and authenticated - Edit access to the target Figma file (view-only will fail)
- The
figma:figma-useskill available
If the Figma MCP tools are not available, prompt the user:
"需要安装 Figma MCP 插件。请运行:
/plugin安装 figma@claude-plugins-official, 然后/reload-plugins --force"
If authentication is needed, initiate OAuth:
Call
mcp__plugin_figma_figma__authenticateand wait for the user to confirm authorization.
What You Must Do When Invoked
Follow these steps in order. Do not skip steps.
Step 1 — Parse URL and validate access
Extract fileKey and optional nodeId from the URL:
URL pattern: https://figma.com/design/{fileKey}/{fileName}?node-id={int1}-{int2}
- fileKey: 22-char alphanumeric string (e.g., "YSNZIphFjVjMWMPd4RhCLA")
- nodeId: "{int1}:{int2}" (e.g., "0:1" for root, "230:8494" for specific frame)
If node-id is absent, use root node 0:1.
Validate access by calling:
mcp__plugin_figma_figma__get_metadata({ fileKey })
If this fails with permission error, tell the user they need edit access and stop.
Step 2 — Discover page structure and key frames
Call get_metadata to get the full page tree. From the metadata, identify:
- Full-screen frames — frames with width ≥ 1200px and height ≥ 700px (typical desktop screens)
- Sub-frames — smaller frames that represent UI components or sections
- Page organization — how frames are grouped (by flow, by feature, etc.)
For each full-screen frame, record:
id(node ID)name(frame name)position(x, y — for ordering)size(width × height)
Sort frames by position (left-to-right, top-to-bottom) to establish reading order.
Example output:
id=1:2 name="首页" pos=(2377,0) size=1440×900
id=230:8494 name="技能库" pos=(2377,1252) size=1440×900
id=235:10138 name="自动化" pos=(2377,3756) size=1440×900
id=26:3543 name="任务执行" pos=(11848,0) size=1440×900
Present a summary to the user:
发现 N 个全屏 frame:
1. 首页 (1:2)
2. 技能库 (230:8494)
3. 自动化 (235:10138)
4. 任务执行 (26:3543)
开始提取...
Step 3 — Capture screenshots
Create the output directory:
mkdir -p .design/screenshots
For each key frame identified in Step 2, call get_screenshot:
mcp__plugin_figma_figma__get_screenshot({
fileKey: "<fileKey>",
nodeId: "<frame-id>",
maxDimension: 1440
})
Download each screenshot using the returned URL:
curl -sL "<screenshot-url>" -o .design/screenshots/<descriptive-name>.png
Naming rules — prioritize Figma frame names:
- Use the Figma frame name directly as the filename, converted to lowercase kebab-case: frame name "首页" →
首页.png, "Skill Library" →skill-library.png, "任务执行" →任务执行.png - Preserve Chinese frame names as-is when the design is primarily in Chinese — do NOT translate to English slugs
- Only convert whitespace and special characters to hyphens: "Home - Default" →
home-default.png - For variant states, append the state: frame "首页" with variant "empty" →
首页-empty.png - For unnamed/ambiguous frames:
screen-N.png(numbered by position order) - If two frames share the same name (across different pages), disambiguate with page prefix:
page-name-frame-name.png
⚠️ IMPORTANT: Verify screenshot names match content. After downloading each screenshot, read the image file back using the Read tool and visually inspect it. Ensure the filename accurately describes what the screenshot shows. Common mistake: confusing
skill-library-*views (card grids, detail modals) withtask-execution-*views (chat panels, deliverables, running states). If a name doesn't match, rename it immediately before proceeding.
After all screenshots are saved, list them with file sizes for verification.
Step 3.1 — Generate screenshots index
After all screenshots are verified, generate .design/screenshots/index.md as a visual directory grouped by functional module.
For each screenshot, read the image file and write an accurate description of what it shows. This file is consumed by /design2code to quickly locate the right visual reference without opening every image.
Format:
# 截图目录
> <Project Name> 全部页面截图,按功能模块分组,文件名直接对应 Figma frame 标签。
---
## 首页 (Home)
| 截图 | 说明 |
|------|------|
|  | 首页 — 居中输入区域、左侧最近项目列表、空聊天面板 |
---
## 技能库 (Skill Library)
| 截图 | 说明 |
|------|------|
|  | 技能库 — 技能卡片网格视图,含搜索栏和分类筛选 |
|  | 技能详情 — 点击技能卡片后打开的技能说明页 |
---
## 任务执行 (Task Execution)
| 截图 | 说明 |
|------|------|
|  | 任务执行中 — 运行中任务视图,聊天消息、步骤进度、输出面板 |
### Skill 调用
| 截图 | 说明 |
|------|------|
|  | 查看调用了的Skill — 展开查看任务中调用的 Skill 列表 |
Rules:
- Every screenshot MUST appear in the index — no missing files
- Group screenshots by functional module using
## 模块中文名 (English Name)headings - Sub-states or sub-views within a module use
###sub-headings (e.g.### Skill 调用,### 产出结果) - Each section is separated by a horizontal rule
--- - Table columns are
截图(inline image) and说明(content description) 说明format:模块名 — <具体页面内容描述>- Screenshot filenames must match the actual files on disk (Figma frame names per naming rules)
- Read each image to verify the description accurately reflects the content
- Sort by functional module grouping first, then by reading order within each group
- If a screenshot was renamed during verification, use the final filename
Step 3.5 — Extract brand assets and icons
Extract visual brand assets and custom icons directly from Figma for use in the generated codebase.
Brand assets (brand/)
Look for these common brand asset types in the Figma file (usually on a "Brand", "Assets", or "Style Guide" page, or as standalone top-level frames):
- Logo / brand mark — the primary logo, wordmark, or brand symbol
- App icon — square app icon (usually 512×512 or similar)
- Mascot / character — brand character or illustration (if present)
- Favicon — browser tab icon (if present)
For each found brand asset:
mcp__plugin_figma_figma__download_assets({
fileKey: "<fileKey>",
nodeId: "<brand-node-id>",
defaultFormat: "svg" // SVG for logo/mark; use "png" for raster-only assets
})
Save to .design/brand/:
logo-mark.svgorlogo-mark.pnglogo-wordmark.svg(if separate)app-icon.pngfavicon.pngorfavicon.svgmascot.png(if present)
If a brand page is not found, search for nodes named "logo", "icon", "brand", "mark" across all pages using get_metadata and inspect their names.
Custom icons (icons/)
For custom SVG icons that are NOT standard Lucide icons (i.e., branded or unique icons):
- Identify icon frames/components in Figma — usually small frames (16×16 to 48×48) grouped under "Icons" or "UI Kit" sections
- Export each as SVG:
mcp__plugin_figma_figma__download_assets({
fileKey: "<fileKey>",
nodeId: "<icon-node-id>",
defaultFormat: "svg"
})
- Save to
.design/icons/with descriptive kebab-case names:sparkle-brand.svgnuo-logo.svg- etc.
Document all extracted icons in ICONS.md under a "## Custom Icons" section, listing filename, purpose, and size.
⚠️ This step is mandatory. Even if there's no dedicated "Brand" or "Icons" page, search for custom icons within the main frames. Look for:
- Nodes named "Icon/*" (e.g.,
Icon/Arrow Left,Icon/历史会话)- Brand marks near text like "NuoNuo", "logo", "品牌"
- Small frames (16×16 to 48×48) grouped as icon components
- Nodes with names like "Credit-rating", "Calendar / Alarm", "magic-tool" that represent custom icons
Use
get_metadatato search all nodes, thendownload_assetswithdefaultFormat: "svg"for each identified icon. If truly no custom icons exist, note it explicitly in the final report.
Step 4 — Extract design context from key screens
For the 3–6 most information-dense screens, call get_design_context:
mcp__plugin_figma_figma__get_design_context({
fileKey: "<fileKey>",
nodeId: "<frame-id>",
clientFrameworks: "react",
clientLanguages: "typescript,html,css"
})
This returns React + Tailwind code that reveals:
- Exact hex colors used (from Tailwind arbitrary values like
bg-[#FAFAFA]) - Font families, sizes, weights (from
font-['PingFang_SC'],text-[14px],font-semibold) - Spacing values (from
gap-[24px],p-[14px],w-[264px]) - Border radius (from
rounded-[16px],rounded-[8px]) - Shadows (from
shadow-[...]) - Component structure (how elements nest and relate)
- Layout patterns (flex, grid, fixed widths)
Prioritize screens that show:
- The main landing/home page (reveals base layout, input patterns)
- A page with cards/grid (reveals card components, spacing, shadows)
- A complex page with multiple panels (reveals layout system, panel structure)
- A page with controls/toggles (reveals interactive component patterns)
From the returned code, extract and tabulate:
Colors
Scan all Tailwind color values. Group into:
- Backgrounds:
bg-[#...]values - Text:
text-[#...]values - Borders:
border-[#...]values - Accents: unique colors used sparingly (brand, success, error)
Typography
Scan all text styling. Record:
- Font families (PingFang SC, Montserrat, Inter, etc.)
- Font sizes and which elements use them
- Font weights (400, 500, 600)
- Line heights
Spacing
Scan all spacing values. Group by magnitude:
- xs (2–4px), sm (6–8px), md (10–12px), lg (14–16px), xl (20–24px), 2xl (32px+)
Rounded
Scan all border-radius values:
- xs (3px), sm (6px), md (8px), lg (16px), pill (90px+)
Shadows
Extract exact shadow values from shadow-[...] classes.
Components
Identify distinct UI components and their visual properties.
Step 4.5 — Extract animations and interactions
After extracting design tokens and components, extract animation definitions and interaction states from Figma.
Extract animations
Look for animation definitions in the Figma file:
Identify animation components:
- Search for Smart Animate transitions
- Look for prototype connections with animation effects
- Find components with multiple states showing transitions
Extract animation properties:
- Animation type (opacity, transform, scale, rotate)
- Duration (ms)
- Easing function (ease-in, ease-out, ease-in-out, spring, linear)
- From/to values
- Figma node IDs for reference
Generate
.design/ANIMATIONS.md:
# Animations and Transitions
## Extraction Info
- Figma file: <fileKey>
- Extracted: <timestamp>
- Animation count: <N>
## Transitions
### fade-in
- **Type**: opacity
- **From**: 0
- **To**: 1
- **Duration**: 200ms
- **Easing**: ease-out
- **Figma node**: 123:456
- **Usage**: Modal dialogs, dropdown menus
### slide-up
- **Type**: transform (translateY)
- **From**: 20px
- **To**: 0
- **Duration**: 300ms
- **Easing**: ease-out
- **Figma node**: 123:457
- **Usage**: Notifications, tooltips
## Keyframe Animations
### spinner
- **Property**: rotate
- **Keyframes**:
- 0%: rotate(0deg)
- 100%: rotate(360deg)
- **Duration**: 1s
- **Loop**: infinite
- **Easing**: linear
- **Figma node**: 234:567
## Easing Functions
- `ease-in`: cubic-bezier(0.4, 0, 1, 1)
- `ease-out`: cubic-bezier(0, 0, 0.2, 1)
- `ease-in-out`: cubic-bezier(0.4, 0, 0.2, 1)
- `spring`: cubic-bezier(0.34, 1.56, 0.64, 1)
## Duration Scale
- `fast`: 100ms — micro-interactions (button clicks)
- `normal`: 200ms — standard transitions (hover, focus)
- `slow`: 300ms — complex animations (modals, page transitions)
If no animations are found in Figma, generate a template with common defaults.
Extract interaction states
Look for component variants and interaction states:
Identify component variants:
- Find components with multiple states (default, hover, active, disabled, loading)
- Extract property changes for each state
- Record transition effects between states
Generate
.design/INTERACTIONS.md:
# Interaction States
## Extraction Info
- Figma file: <fileKey>
- Extracted: <timestamp>
- Interactive components: <N>
## Button Interactions
### Hover State
- **Background**: primary-500 → primary-600
- **Shadow**: none → 0 4px 12px rgba(10, 108, 255, 0.3)
- **Transition**: fade-in 200ms
- **Figma component**: 20:1 (variant: primary)
### Active State
- **Background**: primary-600 → primary-700
- **Scale**: scale(0.98)
- **Transition**: scale 100ms
### Focus State
- **Outline**: 2px solid primary-500
- **Outline offset**: 2px
- **Usage**: Keyboard navigation (accessibility)
### Disabled State
- **Background**: gray-200
- **Text**: gray-400
- **Cursor**: not-allowed
### Loading State
- **Show**: spinner icon
- **Disable**: click events
- **Spinner animation**: spinner 1s linear infinite
## Card Interactions (hoverable)
### Hover State
- **Shadow**: card → enhanced 20%
- **Translate**: translateY(0) → translateY(-2px)
- **Transition**: slide-up 300ms
## Input Interactions
### Focus State
- **Border**: border-input → primary-500
- **Shadow**: 0 0 0 3px rgba(10, 108, 255, 0.1)
- **Transition**: fade-in 200ms
### Error State
- **Border**: error (#DB3543)
- **Shadow**: 0 0 0 3px rgba(219, 53, 67, 0.1)
- **Show**: error message text
## Interaction Matrix
| Component | Default | Hover | Active | Focus | Disabled | Loading |
|-----------|---------|-------|--------|-------|----------|---------|
| Button (primary) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Button (secondary) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Card | ✓ | ✓ (hoverable) | - | - | - | - |
| Input | ✓ | - | - | ✓ | ✓ | ✓ |
| Modal | ✓ | - | - | - | - | - |
If no interaction states are found, generate a template with common defaults.
Update MANIFEST.json
Add animation and interaction metadata to MANIFEST.json:
{
"animations": {
"count": 8,
"file": "ANIMATIONS.md",
"types": ["transition", "keyframe"],
"figmaNodeIds": ["123:456", "123:457", "234:567"]
},
"interactions": {
"count": 6,
"file": "INTERACTIONS.md",
"components": ["button", "card", "input"],
"states": ["default", "hover", "active", "focus", "disabled", "loading"]
}
}
Step 5 — Generate DESIGN.md
Write .design/DESIGN.md following the design.md spec:
---
name: <Project Name>
colors:
<token-name>: "<hex>"
...
typography:
<token-name>:
fontFamily: <family>
fontWeight: <weight>
fontSize: <size>
lineHeight: <height>
...
rounded:
<token>: <value>
...
spacing:
<token>: <value>
...
shadows:
<token>:
offset: <value>
blur: <value>
color: <value>
...
components:
<component-name>:
backgroundColor: "{colors.<token>}"
textColor: "{colors.<token>}"
rounded: "{rounded.<token>}"
...
---
## Overview
<2-3 paragraphs: what the product is, core design principles, visual philosophy>
## Colors
### Neutrals
<table: token, hex, usage>
### Semantic colors
<table: token, hex, usage>
## Typography
### Scale
<table: token, family, weight, size, line-height, usage>
### Key rules
<bullets: font pairing rules, weight limits, language-specific guidance>
## Layout
### Page structure
<ASCII diagram of overall layout>
### Key dimensions
<table: element, dimensions>
## Elevation & Depth
<table: shadow token, value, usage>
## Shapes
<table: radius token, value, usage>
## Components
### <Component Name>
<visual spec for each component>
## Do's and Don'ts
### Do
<bullets>
### Don't
<bullets>
Rules:
- YAML front matter uses
{path.to.token}references for component values - All hex values must be uppercase:
#FAFAFAnot#fafafa - Token names should be semantic:
bg-page,text-primary, notgray-100 - Include a screenshot table in Overview with
references
Step 6 — Generate COMPONENTS.md
Write .design/COMPONENTS.md based on components identified in Step 4:
For each component, document:
## <ComponentName>
<One-line description of what this component does>
**Props:**
```ts
interface <ComponentName>Props {
prop1: type // description
prop2: type // description
}
States:
| State | Visual change | Trigger |
|---|---|---|
| default | ... | initial |
| active | ... | user interaction |
| disabled | ... | condition |
Interactions:
| Trigger | Behavior |
|---|---|
| click | ... |
| hover | ... |
| keyboard | ... |
Dimensions:
- Container: WxH
- Padding: ...
- Radius: ...
**Rules:**
- Props must be TypeScript interfaces
- Every interactive component must list all states
- Dimensions must match values extracted from Figma
- Group related components (Sidebar → SidebarItem, InputArea → FileBadge)
---
### Step 7 — Generate PAGES.md
Write `.design/PAGES.md` with one section per page:
For each page, document:
```markdown
# Page: <pageName> (<Chinese Name>)
## Function
<What this page does, 1-2 sentences>
## Layout
<ASCII diagram showing component arrangement>
- Overall: <layout description>
- Main area: <content arrangement>
## Components
| Component | Position | Count | Notes |
|---|---|---|---|
| Sidebar | left fixed | 1 | route: /path |
| ... | ... | ... | ... |
## Data
```ts
interface <PageName>State {
// page-level state
}
// API endpoints used
// Navigation: where does this page go?
Interactions
| Trigger | Behavior |
|---|---|
| page load | ... |
| user action | ... |
States
| State | Visual | Enter condition |
|---|---|---|
| loading | skeleton | initial |
| empty | illustration + CTA | no data |
| loaded | normal | data present |
Screenshots
**Rules:**
- Every page gets its own `# Page:` section
- ASCII layout diagram is mandatory — it's the most useful part for code generation
- Data section must include TypeScript interfaces for page state
- Screenshots referenced with relative paths from `.design/`
---
### Step 8 — Generate CODE_PATTERNS.md
Write `.design/CODE_PATTERNS.md` with project-specific code conventions:
```markdown
# Code Patterns — <Project Name>
## Tech Stack
| Layer | Choice |
|---|---|
| Framework | React 18 + TypeScript |
| Styling | Tailwind CSS 3 |
| State | Zustand |
| Router | React Router v6 |
| Icons | Lucide React |
## File Naming
<directory structure example>
## Naming Conventions
| Type | Rule | Example |
|---|---|---|
| Components | PascalCase | <SkillCard /> |
| Props | PascalCase + Props | SkillCardProps |
| Hooks | camelCase + use | useProjectList() |
| Events | on + Verb | onSend, onToggle |
## Layout Patterns
### App Shell
```tsx
<code example>
Centered Content
<code example>
Multi-panel
<code example>
Tailwind Color Mapping
<inline vs config decision, with examples>
Component Writing Pattern
<standard component template>
Interaction Patterns
Rules:
- Infer tech stack from context (if the user's project uses different tools, adapt)
- Layout code examples must match dimensions from DESIGN.md
- Use actual hex values from the design in code examples
Step 9 — Generate ICONS.md
Write .design/ICONS.md by auditing all icons visible in screenshots and design context:
# Icons — <Project Name>
## Icon Library
Primary: Lucide React (https://lucide.dev/icons/)
## Icon Inventory
### Navigation
| Icon (Lucide) | Usage | Location | Size |
|---|---|---|---|
| Plus | Create new | Sidebar | 20×20 |
| ... | ... | ... | ... |
### Actions
| Icon | Usage | Location | Size |
|---|---|---|---|
| Send | Submit | InputArea | 18×18 |
| ... | ... | ... | ... |
### Status
| Icon | Usage | Location | Size |
|---|---|---|---|
| Check | Completed | TaskStep | 14×14 |
| ... | ... | ... | ... |
## Usage Convention
```tsx
import { Sparkles } from 'lucide-react'
<Sparkles size={20} color="#181818" strokeWidth={1.5} />
Size Specs
| Context | Size | strokeWidth |
|---|---|---|
| Navigation | 20×20 | 1.5 |
| Buttons | 16–18×18 | 1.5 |
| Status | 14×14 | 1.5 |
**Rules:**
- Map Figma icon shapes to closest Lucide equivalent
- Custom/branded icons go in a separate section with SVG export notes
- Size and strokeWidth must be consistent within each context
---
### Step 10 — Verify and report
Run final verification:
```bash
echo "=== .design/ structure ==="
find .design -type f | sort | while read f; do
size=$(du -h "$f" | cut -f1)
echo " ${f#.design/} ($size)"
done
Report to the user:
✅ 提取完成!生成了 .design/ 目录:
DESIGN.md (N行) 设计系统 token + 视觉规范
CODE_PATTERNS.md (N行) 技术栈 + 代码约定
COMPONENTS.md (N行) N个组件行为规格
PAGES.md (N行) N个页面完整规格
ICONS.md (N行) 图标清单
brand/ (N个) 品牌资源文件 (logo, app-icon, mascot)
icons/ (N个) 自定义 SVG 图标
screenshots/ (N张) 核心页面截图 + index.md 目录映射
生成 UI 时,在 prompt 中引用这些文件即可。
Handling Edge Cases
Figma MCP not installed
需要安装 Figma MCP 插件:
1. 运行 /plugin 安装 figma@claude-plugins-official
2. 运行 /reload-plugins --force
3. 再次运行 /figma2design <url>
Authentication required
Call mcp__plugin_figma_figma__authenticate, present the auth URL to the user, wait for confirmation.
View-only access
⚠️ Figma MCP 需要编辑权限。请在 Figma 中获取编辑权限后重试。
Very large files (>50 frames)
If the file has more than 50 full-screen frames:
- Show the frame list grouped by page
- Ask the user which pages to extract (or
--all) - Process only the selected pages
Mixed languages in design
If the design contains both Chinese and English text:
- Note the primary language in DESIGN.md Overview
- Document font pairing rules (e.g., "PingFang SC for Chinese, Montserrat for Latin brand")
- Include language-specific Do's and Don'ts
No recognizable page structure
If frames are small or don't represent full pages:
- Treat each frame as a component rather than a page
- Generate COMPONENTS.md with more detail
- Skip PAGES.md
- Note in DESIGN.md that the file contains component-level designs only
Tips for Best Results
- Extract from the most complex screen first — it reveals the most tokens and patterns
- Cross-reference multiple screens — a color that appears once might be a one-off; appearing 3+ times means it's a token
- Name tokens semantically —
bg-pageis better thangray-50;text-primaryis better thangray-900 - Include ASCII layout diagrams — they are the single most useful artifact for code generation
- Screenshot everything — even ambiguous frames; the visual is a universal fallback
- Group related components — Sidebar + SidebarItem, InputArea + FileBadge + ProjectBar
- Document empty states — they are often forgotten but critical for complete UI generation