# Af Figma Design Expertise

> Use when performing Figma design round-trip workflows — capturing live UI to Figma, extracting design context back to code, managing custom component mappings, and maintaining Figma project structure.

- Skill: `majiayu000/af-figma-design-expertise` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add majiayu000/af-figma-design-expertise`
- Raw SKILL.md: https://api.skillmd.com/api/skills/majiayu000/af-figma-design-expertise/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: majiayu000 (https://skillmd.com/u/majiayu000)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/majiayu000/af-figma-design-expertise

---


# Figma Design Round-Trip Expertise

Directive knowledge for Figma <> Code design round-trips. Code remains source of truth; Figma is the visual manipulation layer for designers.

## When to Use This Skill

Load this skill when:
- Capturing live UI to Figma for designer review (`generate_figma_design`)
- Extracting design changes from Figma back to code (`get_design_context`)
- Creating or maintaining custom component mappings (`component-map.json`)
- Checking Figma library staleness on `needs:design` label
- Creating or managing Figma project structure (Library, Active Work, Archive)
- Adding Figma page links to Linear issues
- Generating design system rules from project tokens

**Storybook remains primary.** Figma is an optional visual layer — not all projects use it.

## Quick Reference

### Workflow Summary

```
PM refines issue -> adds needs:design label -> Designer edits in Figma -> Engineer agent extracts + implements
```

| Step | Who | Where | Tool |
|------|-----|-------|------|
| Flag design needed | PM | Linear | `needs:design` label |
| Check library freshness | Agent | Storybook vs Figma | Staleness check |
| Capture/sync if stale | Human + Agent | Browser + Figma | `generate_figma_design` |
| Design work | Designer | Figma Active Work | Figma native |
| Link design to issue | Designer | Linear | `## Design` section |
| Extract design | Agent | Figma MCP | `get_metadata` + `get_design_context` |
| Adapt to codebase | Agent | Local | `component-map.json` + `design-system-rules.md` |
| Implement | Agent | Storybook/code | Standard delivery |
| UX review capture | Agent | Figma | `generate_figma_design` |

### Figma MCP Tools

| Tool | MCP Name | Purpose |
|------|----------|---------|
| Capture UI | `generate_figma_design` | Live UI -> editable Figma frames |
| Get Design Context | `get_design_context` | Figma selection -> React + Tailwind code |
| Get Metadata | `get_metadata` | Figma node tree -> XML with names, types, positions |
| Get Variables | `get_variable_defs` | Extract tokens (colors, spacing, typography) |
| Get Screenshot | `get_screenshot` | Screenshot of a Figma node |

### Rate Limits (Pro/Organization Plan)

| Metric | Limit |
|--------|-------|
| Daily tool calls | 200/day per seat |
| Per-minute calls | 15/min per seat |
| Capture calls | Exempt from limits |

### Figma Project Structure

```
Figma Project: "{Product Name}"
|-- [Library] Design System          <- Component reference frames (captured from Storybook)
|-- [File] Active Work               <- Issue-specific design pages
+-- [File] Shipped Archive           <- Completed designs (reference)
```

### Project Configuration

Per-project Figma settings in project config:

```json
{
  "figma": {
    "activeWorkFileId": "FILE_ID",
    "designSystemLibraryId": "LIBRARY_FILE_ID",
    "shippedArchiveFileId": "ARCHIVE_FILE_ID"
  }
}
```

### Custom Mapping Files

| File | Purpose | Generated by |
|------|---------|-------------|
| `.figma/component-map.json` | Maps Figma component names -> codebase imports | Component map generator script |
| `.figma/design-system-rules.md` | Maps hex values -> CSS variable tokens | Design system rules generator script |
| `.figma/last-sync-commit` | Git commit hash of last Figma library sync | Capture script |

### MCP Server Configuration

The Figma MCP server is **pre-configured globally** in AgentFlow's `.mcp.json` -- no per-project setup needed.

No API keys or tokens needed. On first use, the MCP server initiates an OAuth flow in the browser -- the user authenticates with their Figma account directly. Authentication persists across sessions.

**Capture requires a browser.** The OAuth flow and `generate_figma_design` need a browser session. This means capture is human-triggered, not CI/CD automated. Extraction (`get_design_context`, `get_metadata`) works headlessly from agents.

> **Manual setup (non-AgentFlow projects):** Add to `.mcp.json`:
> ```json
> { "figma": { "url": "https://mcp.figma.com/mcp" } }
> ```

## Rules (FOLLOW THESE)

### Source of Truth Rules

1. **Code is ALWAYS source of truth** -- Figma is a visual manipulation layer, not the design source
2. **Tokens flow one-way: code -> Figma** -- Design System Library reflects Storybook. Token changes flow from `globals.css` -> capture -> Figma Library
3. **Storybook remains primary** -- All component design, testing, and sign-off happens in Storybook. Figma supplements, never replaces
4. **MUST NOT duplicate components in Figma** -- All issue work references the Design System Library

### Extraction + Adaptation Rules

5. **MUST use two-step extraction** -- First `get_metadata` (identifies components by name), then `get_design_context` (gets code)
6. **MUST adapt extraction output** -- `get_design_context` returns generic React+Tailwind. Agent MUST read `component-map.json` to replace inline code with real component imports
7. **MUST apply design system rules** -- Agent MUST read `design-system-rules.md` to replace hardcoded hex values with CSS variable tokens
8. **Output is a starting point, not production code** -- Extraction produces absolute positioning and inline styles. Agent adapts layout to use project patterns (flexbox, grid, responsive)

### Round-Trip Rules

9. **MUST limit round-trips to 2-3 cycles** before re-capturing from code -- frames degrade after multiple cycles
10. **MUST remove Figma annotations before extraction** -- Annotations break `get_design_context` output
11. **MUST validate each cycle against original intent** -- Check for layout drift, token loss, component degradation

### Component Map Rules

12. **component-map.json maps Figma names to codebase imports** -- Generated from Storybook stories.json + component source files
13. **MUST regenerate component-map.json when components change** -- Run the generator script after adding/modifying components
14. **Mapping is name-based** -- Figma component/frame names must match Storybook component names for mapping to work

### Variable Rules

15. **`get_variable_defs` only returns DEFAULT mode values** -- Cannot read alternate variable modes
16. **design-system-rules.md maps hex -> CSS variables** -- Generated from `globals.css`, used by agent during adaptation step

### Figma File Management Rules

17. **Each issue gets its own Figma page** -- Named `{ISSUE-ID} {Short Description}`
18. **Frame naming within a page** -- `{ISSUE-ID}/Screen Name/State` (e.g., `AF-124/Dashboard/Default`)
19. **MUST add Figma page URL to Linear issue** -- Under a `## Design` section in the issue description
20. **MUST use `needs:design` label** -- Add when designer input is needed, remove when complete

### Library Sync Rules

21. **Lazy sync on `needs:design`** -- When an issue gets the `needs:design` label, check if the Figma library is stale before the designer starts
22. **Staleness detection** -- Compare `.figma/last-sync-commit` against current HEAD. If `stories.json` or component files changed since last sync, library is stale
23. **Capture requires human** -- Browser OAuth means a human must trigger the capture script. The designer is already in a browser, so they trigger it

## Workflows

### Workflow: Pre-Design Sync Check (on `needs:design`)

**When:** An issue receives the `needs:design` label, before designer starts work.

**Run:**
```bash
npx tsx .claude/scripts/figma/figma-prepare.ts
```

This single command orchestrates:
1. Checks library staleness (`.figma/last-sync-commit` vs HEAD)
2. Regenerates `.figma/component-map.json` from Storybook
3. Regenerates `.figma/design-system-rules.md` from globals.css
4. Reports status: FRESH (proceed) or STALE (re-capture needed)

**If stale:** The script lists which components changed. A human with a browser triggers capture of updated components to the Figma Library file, then runs:
```bash
git rev-parse HEAD > .figma/last-sync-commit
```

**Options:** `--skip-staleness` (initial setup), `--storybook-dir <path>`, `--css <path>`

---

### Workflow: Designer Flow Choice

**When:** Designer starts work on an issue with `needs:design`.

**Steps:**
1. Ask the designer: "Which workflow? (A) Edit existing screens -- capture live UI, tweak in Figma, extract back. (B) Compose new screens -- use Figma library references to assemble new designs."
2. Designer picks their flow
3. Auto-scaffold:
   - Create page in Active Work file: `{ISSUE-ID} {Short Description}`
   - For Flow A: capture current UI into the page
   - For Flow B: open the page ready for composition from library references
   - Add Figma page URL to Linear issue under `## Design`
4. Designer works in Figma
5. On completion: remove `needs:design` label, notify that design is ready for implementation

---

### Workflow: Flow A -- Direct Code <> Figma Round-Trip

**When:** Iterating on existing screens, layout adjustments, spacing/color tweaks, responsive checks.

**Prerequisites:** Figma MCP configured, component-map.json generated, design-system-rules.md generated.

**Steps:**
1. **Capture**: Use `generate_figma_design` to capture live UI from browser to Figma (human-triggered)
2. **Verify**: Check frame quality -- editable layers, correct structure, no flat screenshots
3. **Designer edits**: Designer tweaks visually in Figma (spacing, colors, component swaps)
4. **Extract**: Use `get_metadata` on designer's modified selection (get component tree with names)
5. **Extract code**: Use `get_design_context` on the same selection (get React+Tailwind code)
6. **Adapt**: Read `component-map.json` -- replace inline code with real component imports. Read `design-system-rules.md` -- replace hex values with CSS variable tokens. Fix layout (absolute -> flexbox/grid)
7. **Implement**: Update code based on adapted design intent
8. **Re-capture**: Capture updated UI back to Figma for review (human-triggered)
9. **Iterate**: Repeat steps 3-8 (max 2-3 cycles before fresh capture)

---

### Workflow: Flow B -- Compose from Library References

**When:** New screen design, complex multi-component compositions, design system exploration.

**Prerequisites:** All of Flow A + Figma Library populated with component reference frames.

**Steps:**
1. **Designer assembles**: Designer builds screen in Figma using reference frames from the Library
2. **Extract metadata**: Use `get_metadata` -- identify component names from the Figma tree
3. **Extract code**: Use `get_design_context` -- get React+Tailwind layout code
4. **Adapt**: Map component names to codebase imports via `component-map.json`. Apply design-system-rules. Fix layout
5. **Implement**: Generate adapted code in Storybook/project
6. **Re-capture**: Capture implementation back to Figma for designer review (human-triggered)
7. **Iterate**: Designer reviews, requests changes, agent adapts

---

### Workflow: Agent Extraction (Delivery Phase)

**When:** Engineering agent starts work on an issue that has a Figma design.

**Steps:**
1. Read Linear issue description
2. Look for `## Design` section with Figma link
3. If no Figma link: proceed with Storybook-only (existing behaviour)
4. If found, extract and adapt:

```bash
# Step 4a: Get component tree (save metadata for adaptation)
# Agent calls get_metadata via Figma MCP, saves output to .figma/temp/metadata.xml

# Step 4b: Get raw code (save extraction for adaptation)
# Agent calls get_design_context via Figma MCP, saves code output to .figma/temp/raw-extraction.tsx

# Step 4c: Run adaptation script
npx tsx .claude/scripts/figma/figma-adapt.ts \
  --input .figma/temp/raw-extraction.tsx \
  --metadata .figma/temp/metadata.xml \
  --output .figma/temp/adapted-code.tsx
```

The `figma-adapt.ts` script:
- Reads `component-map.json` -- maps Figma component names to real imports
- Reads `design-system-rules.md` -- replaces hex values with CSS variable tokens
- Identifies components from metadata names
- Outputs adapted code with real imports and project tokens

5. Agent uses adapted output as the basis for implementation (still needs layout fixes -- absolute -> flexbox/grid)

---

### Workflow: UX Review (Delivery Phase)

**When:** Implementation is ready for designer review, before PR.

**Steps:**
1. Agent captures implemented screens to Figma Active Work file (human-triggered capture)
2. Frames appear alongside the designer's original Figma design
3. Designer compares implementation vs design intent
4. Designer approves or requests changes
5. If changes needed: agent extracts feedback, adapts, re-implements
6. If approved: PR proceeds, final state captured to Shipped Archive

---

### Workflow: Initial Project Setup

**When:** Adding Figma integration to a new project.

**Steps:**
1. **Figma MCP** -- Pre-configured globally in AgentFlow. Verify with `/mcp` command
2. **Create Figma project structure** -- Library + Active Work + Shipped Archive files in Figma
3. **Record file IDs** -- Add to project config (see Project Configuration above)
4. **Generate component-map.json** -- Run component map generator script against Storybook stories.json
5. **Generate design-system-rules.md** -- Run rules generator script against globals.css
6. **Initial library capture** -- Capture Storybook component stories to Figma Library file (human-triggered)
7. **Record sync commit** -- Write current git commit hash to `.figma/last-sync-commit`
8. **Test extraction cycle** -- Capture a page -> extract -> adapt -> verify code quality

---

## Phase Integration

### Where Figma Fits in AgentFlow Phases

**During Refinement:**
- PM flags `needs:design` on an issue
- Pre-design sync check runs (staleness detection)
- Designer creates/edits designs in Figma
- Figma page link added to Linear issue
- Part of existing Refinement phase -- no new status needed

**During Delivery (In Progress):**
- Engineering agent reads Figma link from Linear issue
- Agent extracts + adapts code using custom mapping
- UX Review gate: agent captures implementation back to Figma for designer comparison
- Part of existing Delivery phase -- no new status needed

**Post-Delivery:**
- Final implementation captured to Shipped Archive in Figma
- If components changed: `.figma/last-sync-commit` becomes stale (detected on next `needs:design`)

### Role Responsibilities

| Role | Figma Responsibilities |
|------|----------------------|
| **PM** | Adds `needs:design` label; reviews Figma designs as part of mini-PRD approval |
| **Designer** | Works in Figma (ideation + tweaking); triggers library captures when stale; approves UX review |
| **Engineer (Agent)** | Extracts from Figma; adapts using component-map + rules; captures for UX review |

## Known Limitations

| Limitation | Impact | Workaround |
|-----------|--------|------------|
| Extraction returns absolute positioning | Layout needs manual adaptation | Agent converts to flexbox/grid using project patterns |
| Tokens lost in extraction (hardcoded hex) | Must map back to CSS variables | Agent reads design-system-rules.md during adaptation |
| Component classes lost in extraction | Inline styles instead of imports | Agent reads component-map.json during adaptation |
| Always outputs React+Tailwind | Framework mismatch for non-React projects | Agent adapts to target framework |
| Single viewport capture | No responsive breakpoints | Capture at multiple breakpoints if needed |
| Capture requires browser | Cannot automate in CI/CD | Human triggers captures; acceptable since designer is in browser |
| Code Connect requires Enterprise plan | Cannot use native Figma component mapping | Custom component-map.json replaces Code Connect at agent layer |
| Frame degradation after 3+ cycles | Increasing noise in extracted code | Re-capture from code every 2-3 cycles |
| Annotations break get_design_context | Extraction fails | Remove annotations before extraction |

## Environment Variables

No Doppler secrets required. The Figma MCP server uses browser-based OAuth -- each user authenticates with their own Figma account on first use.

## Essential Reading

- [Figma Setup Guide](../../docs/guides/figma-setup-guide.md) -- Step-by-step project setup
- [UX Design Expertise](../af-ux-design-expertise/SKILL.md) -- Primary design workflow (Storybook)
- [Research Spec](../../../.agentflow/research/figma-code-round-trip-spec.md) -- Full analysis and risk register

---

**Remember:**
1. Code is source of truth -- Figma is a visual layer, not the design source
2. Two-step extraction: `get_metadata` (component names) then `get_design_context` (code)
3. ALWAYS adapt extraction output using component-map.json + design-system-rules.md
4. Lazy sync: check library staleness on `needs:design`, not on every component change
5. Capture requires a browser -- human-triggered, not automated
6. Limit round-trips to 2-3 cycles before re-capturing from code
7. Remove annotations before extraction
8. Each issue gets its own Figma page, linked in Linear issue `## Design` section
9. `needs:design` label signals designer input is needed

