---
title: "Figma Skill: Build / Update Screens from Design System"
aliases: [figma-generate-design-skill, figma-build-screens, figma-screen-from-design-system]
tags: [figma, mcp, design-system, claude-code, skill, components, variables]
sources: [raw/Skill Build  Update Screens and Views from Design System.md]
created: 2026-05-15
updated: 2026-05-15
---

# Figma Skill: Build / Update Screens from Design System

Skill for creating or updating **composed Figma views** (pages, modals, drawers, sidebars, panels) by reusing the published design system — components, variables, and styles — rather than drawing primitives with hardcoded values.

**Always load `figma-use` before any `use_figma` call** — it contains critical rules (color ranges, font loading) that apply to every script. Pass `skillNames: "figma-generate-design"` in all `use_figma` calls (logging parameter).

## Skill Boundaries

| Use this skill | Switch to |
|---|---|
| Composed views (screens, modals, drawers) from design system instances | `figma-implement-design` — generating code from a Figma design |
| New or updated multi-section containers | `figma-use` directly — creating new reusable components/variants |
| | `figma-code-connect` — writing Code Connect mappings |

## Parallel Workflow (Web Apps with Images)

When the source is a **web app** with images, run both in parallel:

1. Build via `use_figma` + design system components (this skill's workflow)
2. Run `generate_figma_design` to capture a pixel-perfect browser screenshot

Then merge: copy `imageHash` values from the capture into the `use_figma` output. Delete the capture afterward.

> **Mandatory when source contains images** — `use_figma` Plugin API cannot fetch external image URLs; it can only reuse `imageHash` values already in the file.

## Required Workflow (6 Steps)

### Step 1 — Understand the Deliverable

- Read relevant source files; identify major sections (Header, Hero, Panels, Footer / Title Bar, Form, Action Bar, etc.)
- List UI components per section (buttons, inputs, cards, nav pills, etc.)
- Check for images → if present on a web app, start `generate_figma_design` capture in parallel now

### Step 2 — Collect Component Keys, Variables, Styles

**Hard gate:** no `use_figma` canvas mutations until all Step 2 rows are filled.

#### 2a: Components (priority order)

1. **Code Connect files first** — search `*.figma.ts`, `*.figma.tsx`, `*.figma.js`, `@FigmaConnect` annotations. Parse `fileKey` + `nodeId` from URL; resolve component key via `figma.getNodeByIdAsync()` on the library file. Batch lookups in one call.
2. **Inspect existing screens** — walk `INSTANCE` nodes in an existing frame, collect `mainComponent` keys. Most authoritative source.
3. **`search_design_system` (last resort)** — only if unresolved after 1 & 2. Search broadly with synonyms ("button"/"btn", "nav"/"pill"/"tab", etc.). Also read `componentProperties` for TEXT/BOOLEAN property keys needed in Step 4.

#### 2b: Variables (colors, spacing, radii)

- `getLocalVariableCollectionsAsync()` returns **local only** — empty result ≠ no variables exist
- Use `search_design_system` with `includeVariables: true` for library variables (run parallel queries: "gray", "background", "space", "radius", etc.)
- Inspect existing screen's `boundVariables` for the most authoritative map
- Import library variables: `figma.variables.importVariableByKeyAsync(key)`

#### 2c: Styles (text, effect/shadow)

- `search_design_system` with `includeStyles: true` → "heading", "body", "shadow", "elevation"
- Or inspect existing screen: collect `textStyleId` / `effectStyleId` per node
- Import: `figma.importStyleByKeyAsync(key)`

### Step 3 — Create Wrapper Frame First

Create the wrapper in its own `use_figma` call before building any sections. Return its ID.

```js
const wrapper = figma.createAutoLayout("VERTICAL");
wrapper.name = "VIEW_NAME";
wrapper.resize(WIDTH, 100); // 1440 full page / 640 modal / 360 drawer
wrapper.layoutSizingHorizontal = "FIXED";
wrapper.x = maxX + 200; wrapper.y = 0;
return { wrapperId: wrapper.id };
```

> **Never** build sections as top-level children and reparent later — `appendChild()` across calls silently fails.

### Step 4 — Build Each Section Inside Wrapper

One section per `use_figma` call. Fetch wrapper by ID, append sections directly.

Key rules:
- Import components via `figma.importComponentSetByKeyAsync(key)`
- Bind variables: `setBoundVariable("paddingLeft", spacingVar)` and `setBoundVariableForPaint()` for colors
- Apply text styles: `node.textStyleId = style.id`
- Override instance text via `setProperties({ "Label#2:0": "Actual text" })` — more reliable than direct `characters` manipulation
- Set `layoutSizingHorizontal = "FILL"` **after** appending to wrapper
- `get_screenshot` after each section — check for cropped text, overlapping, wrong variants

**What to build manually vs import:**

| Build manually | Import from design system |
|---|---|
| Wrapper frame, section containers, layout grids | Components (buttons, cards, inputs, nav) |
| | Variables (fills/strokes/spacing/radii) |
| | Text styles, effect styles |

### Step 5 — Validate Full View + Transfer Images

- `get_screenshot` per section (not just the full view — resolution hides detail)
- Check: cropped text, overlapping elements, placeholder text, blank image frames, wrong variants
- Transfer images from `generate_figma_design` capture: find `fill.type === "IMAGE"` nodes, copy `imageHash` to matching target frames
- Delete capture after transfer

### Step 6 — Updating Existing Views

1. `get_metadata` to inspect existing structure
2. Locate nodes by ID/name; swap with `existingButton.swapComponent(newVariant)`
3. Update text/variants/layout selectively; remove deprecated sections
4. Validate each modification with `get_screenshot`

## Error Recovery

1. STOP on error — don't retry immediately
2. Read error; use `get_metadata` or `get_screenshot` to inspect state
3. Fix the script; retry (failed scripts are atomic — nothing persists on error)
4. Each section call is independent — previous sections are safe

## Key Takeaways

- **Never hardcode hex colors or pixel spacing** — always use design system variables (`setBoundVariable`, `setBoundVariableForPaint`)
- **Discovery order matters:** Code Connect → existing screens → `search_design_system` (last resort)
- **`getLocalVariableCollectionsAsync()` empty ≠ no variables** — always also run `search_design_system` for library vars
- **Create wrapper first, sections inside** — cross-call `appendChild()` silently fails
- **One section per `use_figma` call** — validate visually after each
- **Images require parallel `generate_figma_design`** — `use_figma` cannot fetch external image URLs
- **Override text via `setProperties()`** not `characters` — use component property keys from Step 2a discovery
- **`figma-use` is a prerequisite** — load it before every `use_figma` call

## Related Articles

- [[wiki/claude-code/figma-mcp-skills|figma-mcp-skills]] — overview of all 8 Figma MCP skills
- [[wiki/claude-code/figma-mcp-code-to-canvas|figma-mcp-code-to-canvas]] — `generate_figma_design` for pixel-perfect captures
- [[wiki/claude-code/figma-mcp-code-connect|figma-mcp-code-connect]] — Code Connect file structure and mappings
- [[wiki/claude-code/figma-mcp-guide|figma-mcp-guide]] — Figma MCP server overview and capabilities
