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
├── home-default.png
├── skill-library.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) |
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:
"The Figma MCP plugin needs to be installed. Please run:
/plugininstall figma@claude-plugins-official, then/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:
- Use lowercase kebab-case:
home-default.png,skill-library.png - Include the page purpose, not the Figma frame name (translate Chinese to English slug)
- For variant states:
home-project-selected.png,home-with-files.png - For unnamed/ambiguous frames:
screen-N.png(numbered by position order)
After all screenshots are saved, list them with file sizes for verification.
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.
If no brand page or custom icons are found in the Figma file, skip this step and note it 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张) 核心页面截图
生成 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