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:designlabel - 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:
{
"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:{ "figma": { "url": "https://mcp.figma.com/mcp" } }
Rules (FOLLOW THESE)
Source of Truth Rules
- Code is ALWAYS source of truth -- Figma is a visual manipulation layer, not the design source
- Tokens flow one-way: code -> Figma -- Design System Library reflects Storybook. Token changes flow from
globals.css-> capture -> Figma Library - Storybook remains primary -- All component design, testing, and sign-off happens in Storybook. Figma supplements, never replaces
- MUST NOT duplicate components in Figma -- All issue work references the Design System Library
Extraction + Adaptation Rules
- MUST use two-step extraction -- First
get_metadata(identifies components by name), thenget_design_context(gets code) - MUST adapt extraction output --
get_design_contextreturns generic React+Tailwind. Agent MUST readcomponent-map.jsonto replace inline code with real component imports - MUST apply design system rules -- Agent MUST read
design-system-rules.mdto replace hardcoded hex values with CSS variable tokens - 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
- MUST limit round-trips to 2-3 cycles before re-capturing from code -- frames degrade after multiple cycles
- MUST remove Figma annotations before extraction -- Annotations break
get_design_contextoutput - MUST validate each cycle against original intent -- Check for layout drift, token loss, component degradation
Component Map Rules
- component-map.json maps Figma names to codebase imports -- Generated from Storybook stories.json + component source files
- MUST regenerate component-map.json when components change -- Run the generator script after adding/modifying components
- Mapping is name-based -- Figma component/frame names must match Storybook component names for mapping to work
Variable Rules
get_variable_defsonly returns DEFAULT mode values -- Cannot read alternate variable modes- design-system-rules.md maps hex -> CSS variables -- Generated from
globals.css, used by agent during adaptation step
Figma File Management Rules
- Each issue gets its own Figma page -- Named
{ISSUE-ID} {Short Description} - Frame naming within a page --
{ISSUE-ID}/Screen Name/State(e.g.,AF-124/Dashboard/Default) - MUST add Figma page URL to Linear issue -- Under a
## Designsection in the issue description - MUST use
needs:designlabel -- Add when designer input is needed, remove when complete
Library Sync Rules
- Lazy sync on
needs:design-- When an issue gets theneeds:designlabel, check if the Figma library is stale before the designer starts - Staleness detection -- Compare
.figma/last-sync-commitagainst current HEAD. Ifstories.jsonor component files changed since last sync, library is stale - 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:
npx tsx .claude/scripts/figma/figma-prepare.ts
This single command orchestrates:
- Checks library staleness (
.figma/last-sync-commitvs HEAD) - Regenerates
.figma/component-map.jsonfrom Storybook - Regenerates
.figma/design-system-rules.mdfrom globals.css - 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:
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:
- 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."
- Designer picks their flow
- 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
- Create page in Active Work file:
- Designer works in Figma
- On completion: remove
needs:designlabel, 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:
- Capture: Use
generate_figma_designto capture live UI from browser to Figma (human-triggered) - Verify: Check frame quality -- editable layers, correct structure, no flat screenshots
- Designer edits: Designer tweaks visually in Figma (spacing, colors, component swaps)
- Extract: Use
get_metadataon designer's modified selection (get component tree with names) - Extract code: Use
get_design_contexton the same selection (get React+Tailwind code) - Adapt: Read
component-map.json-- replace inline code with real component imports. Readdesign-system-rules.md-- replace hex values with CSS variable tokens. Fix layout (absolute -> flexbox/grid) - Implement: Update code based on adapted design intent
- Re-capture: Capture updated UI back to Figma for review (human-triggered)
- 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:
- Designer assembles: Designer builds screen in Figma using reference frames from the Library
- Extract metadata: Use
get_metadata-- identify component names from the Figma tree - Extract code: Use
get_design_context-- get React+Tailwind layout code - Adapt: Map component names to codebase imports via
component-map.json. Apply design-system-rules. Fix layout - Implement: Generate adapted code in Storybook/project
- Re-capture: Capture implementation back to Figma for designer review (human-triggered)
- 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:
- Read Linear issue description
- Look for
## Designsection with Figma link - If no Figma link: proceed with Storybook-only (existing behaviour)
- If found, extract and adapt:
# 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
- 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:
- Agent captures implemented screens to Figma Active Work file (human-triggered capture)
- Frames appear alongside the designer's original Figma design
- Designer compares implementation vs design intent
- Designer approves or requests changes
- If changes needed: agent extracts feedback, adapts, re-implements
- If approved: PR proceeds, final state captured to Shipped Archive
Workflow: Initial Project Setup
When: Adding Figma integration to a new project.
Steps:
- Figma MCP -- Pre-configured globally in AgentFlow. Verify with
/mcpcommand - Create Figma project structure -- Library + Active Work + Shipped Archive files in Figma
- Record file IDs -- Add to project config (see Project Configuration above)
- Generate component-map.json -- Run component map generator script against Storybook stories.json
- Generate design-system-rules.md -- Run rules generator script against globals.css
- Initial library capture -- Capture Storybook component stories to Figma Library file (human-triggered)
- Record sync commit -- Write current git commit hash to
.figma/last-sync-commit - Test extraction cycle -- Capture a page -> extract -> adapt -> verify code quality
Phase Integration
Where Figma Fits in AgentFlow Phases
During Refinement:
- PM flags
needs:designon 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-commitbecomes stale (detected on nextneeds: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 -- Step-by-step project setup
- UX Design Expertise -- Primary design workflow (Storybook)
- Research Spec -- Full analysis and risk register
Remember:
- Code is source of truth -- Figma is a visual layer, not the design source
- Two-step extraction:
get_metadata(component names) thenget_design_context(code) - ALWAYS adapt extraction output using component-map.json + design-system-rules.md
- Lazy sync: check library staleness on
needs:design, not on every component change - Capture requires a browser -- human-triggered, not automated
- Limit round-trips to 2-3 cycles before re-capturing from code
- Remove annotations before extraction
- Each issue gets its own Figma page, linked in Linear issue
## Designsection needs:designlabel signals designer input is needed