From figma-suite
Bidirectional design system sync between code tokens and Figma variables, component library generation, screen design composition, and design audit. Use when syncing design tokens to/from Figma, building Figma component libraries, designing new screens in Figma, or auditing Figma files for design system compliance.
How this skill is triggered — by the user, by Claude, or both
Slash command
/figma-suite:figma-suiteThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Bridges a codebase design system and a Figma file. Handles token sync, component library generation, screen design, auditing, and guideline updates — all through Figma MCP tools.
reference/component-contracts.mdreference/config-schema.mdreference/figma-file-structure.mdreference/naming-conventions.mdreference/plugin-api-patterns.mdreference/token-map.mdworkflows/audit.mdworkflows/build-library.mdworkflows/design-screen.mdworkflows/setup.mdworkflows/sync-tokens.mdworkflows/update-guidelines.mdBridges a codebase design system and a Figma file. Handles token sync, component library generation, screen design, auditing, and guideline updates — all through Figma MCP tools.
Progressive disclosure: Only load workflow and reference files when actively executing that workflow. Do not eagerly read all linked files — they are large and consume context unnecessarily.
This skill requires the official Figma MCP server:
| Server | Tools used |
|---|---|
figma (remote server at https://mcp.figma.com/mcp) | mcp__figma__get_design_context, mcp__figma__get_screenshot, mcp__figma__get_metadata, mcp__figma__search_design_system, mcp__figma__use_figma, mcp__figma__get_variable_defs, mcp__figma__generate_figma_design |
The mcp__figma__use_figma tool accepts Figma Plugin API code, which covers all operations including variable creation, component building, and batch updates — no second server needed.
If the server is not configured, guide the user to set it up:
claude plugin install figma@claude-plugins-officialhttps://mcp.figma.com/mcp and authenticate via OAuthIf the Figma MCP server is connected but returns errors:
use_figma — common causes are stale nodeIds or missing fontsRun /figma-suite setup to generate config and project mappings.
The skill supports three usage scenarios. During setup, it detects which applies and asks the user where to save:
Scenario 1: Standalone (no codebase)
The user launches Claude from their home folder or any non-project directory. Generated files go to <HOME>/.claude/figma-suite/{project-name}/. This is the only option — there's no project directory to save into.
Scenario 2: Inside a project — user chooses location The user launches Claude from a project directory. Setup asks:
Where should I save the figma-suite workspace?
1. Project-level (default) — .figma-suite/ in this project directory (shared with teammates via git)
2. Global — <HOME>/.claude/figma-suite/{project-name}/ (personal, not committed)
Reply with a number:
{project-root}/.figma-suite/): config and generated files live in the project. Teammates who install the skill see the same config. Add .figma-suite/ to .gitignore if you don't want it committed, or commit it to share.<HOME>/.claude/figma-suite/{project-name}/): config is personal to this machine. Multiple users can have different configs for the same project.Scenario 3: Skill installed at project level only
The skill lives in .claude/skills/figma-suite/ inside the project. Works identically to Scenario 2 — setup asks the same location question.
<HOME> — the user's home directory (~ on macOS/Linux, %USERPROFILE% on Windows). Always resolve to the absolute path at runtime.
When invoked, the skill searches for an existing workspace in this order:
{project-root}/.figma-suite/config.json — project-level workspace<HOME>/.claude/figma-suite/*/config.json — global workspace matching projectPathdesign-tokens/*.tokens.json — W3C Design Token Format (DTF/DTCG)tokens/**/*.json — Style Dictionary formattailwind.config.js / tailwind.config.ts — Tailwind theme tokenssrc/global.css or src/styles/globals.css — CSS custom propertiestheme.ts / theme.js — JS theme objectsWhen auto-discovering, read each found file and classify tokens into: colors, typography, spacing, radii, shadows, other.
The skill auto-detects whether you're in a codebase (scans tokens + components) or standalone (scans Figma file only).
A project can reference multiple library files (published DS sources) and multiple design files (where screens are composed). See config-schema.md for the full config structure, field reference, and design rules file format.
Dispatch based on $ARGUMENTS:
| Argument | Workflow | Description |
|---|---|---|
setup | setup.md | First-time init: scan project, generate token map and component contracts |
sync | sync-tokens.md | Diff code tokens vs Figma variables, show drift report, apply after approval |
sync --to-figma | sync-tokens.md | One-way push: code to Figma |
sync --to-code | sync-tokens.md | One-way pull: Figma to code tokens |
build-library | build-library.md | Generate or rebuild Figma component library from code components |
design <description> | design-screen.md | Compose a new screen in Figma using design system components |
audit | audit.md | Read-only audit of Figma file for DS compliance |
update-guide | update-guidelines.md | Sync design guidelines between code docs and Figma annotations |
| (no argument) | Check if setup has been run; if not, run setup. Otherwise show the workflow menu. |
These rules apply across ALL workflows:
Whenever presenting the user with a choice, always use a numbered list with a clear default marked. Let the user reply with just a number or type a custom answer. Never present walls of text without structure.
Pick a platform:
1. mobile-ios (default) — 393×852, iOS status bar, tab bar
2. mobile-android — 393×852, Android status bar, bottom nav
3. web-desktop — 1440×900, top nav
4. custom — define your own
Reply with a number or describe your setup:
For yes/no questions, offer both options explicitly:
Apply all 9 changes? (yes / no / let me choose)
For text input, show what's expected:
Project name (kebab-case, e.g. "my-mobile-app"):
Every write operation must produce a dry-run report first. Never write to Figma or code without user approval.
After every visual change in Figma, capture a screenshot with mcp__figma__get_screenshot and verify the result. Maximum 3 fix iterations per section.
Tokens, variables, components, and pages are never deleted. Stale items are flagged in the report for the user to decide.
When updating Figma files, back up or duplicate affected frames before overwriting. When updating code tokens, show the diff before writing.
Do one thing per use_figma call. The most common cause of bugs is trying to do too much in a single call. Break complex tasks into small steps:
use_figma to discover existing pages, components, variables, naming conventionsreturn { createdNodeIds: [...], mutatedNodeIds: [...] }get_metadata for structure, get_screenshot for visualsNever parallelize use_figma calls. Each must complete and be verified before the next.
figma.currentPage always starts on the first page at the beginning of each use_figma call. If your workflow targets a non-default page, call await figma.setCurrentPageAsync(page) at the start of each call. The sync setter figma.currentPage = page throws — always use the async version.
use_figma is atomic — failed scripts do NOT execute. If a script errors, no changes are made to the file. The file remains in the exact state before the call. This means it's safe to retry after fixing the script — no cleanup needed.
When use_figma returns an error:
get_metadata or get_screenshot to check file stateFor code/file write failures (non-atomic):
use_figma timeout → split the batch into smaller chunksget_metadata or use_figmaThe skill uses a two-collection model that works across token formats:
Primitives Collection (1 mode: "Value")
├── Raw color values (hex)
├── Raw spacing values (px)
├── Raw typography values (px, font names)
└── Hidden from consumers (scope: [])
Semantic Collection (N modes: "Light", "Dark", etc.)
├── Aliases into Primitives
├── Purpose-named (background, foreground, accent, surface, etc.)
└── Scoped to specific properties (FILL_COLOR, STROKE_COLOR, etc.)
| Token type | Figma scopes |
|---|---|
| Primitive colors | [] (hidden) |
| Semantic colors | ["FILL_COLOR", "STROKE_COLOR"] |
| Spacing | ["GAP", "WIDTH_HEIGHT"] |
| Radii | ["CORNER_RADIUS"] |
| Font size | ["FONT_SIZE"] |
| Font family | ["FONT_FAMILY"] |
| Font weight | ["FONT_WEIGHT"] |
| Line height | ["LINE_HEIGHT"] |
All variables must have codeSyntax with the var() wrapper for web consumption:
codeSyntax: { WEB: "var(--token-name)" }
Always use mcp__figma__use_figma with Plugin API to read local file content. The read-only MCP tools (get_variable_defs, search_design_system) only return published library data and may fail on local/unpublished content. To reliably read what's actually in the file:
| Task | Approach |
|---|---|
| Local variables & collections | use_figma → figma.variables.getLocalVariableCollectionsAsync() + getVariableByIdAsync() |
| Local text styles | use_figma → figma.getLocalTextStylesAsync() |
| Local components | use_figma → figma.root.findAllWithCriteria({ types: ["COMPONENT_SET"] }) |
| Local standalone components | use_figma → figma.root.findAllWithCriteria({ types: ["COMPONENT"] }) |
| Page structure | use_figma → figma.root.children.map(p => ({ id: p.id, name: p.name })) |
Critical use_figma rules for reading:
return JSON.stringify(result) — never console.log(). Console output is discarded; only return values come back.These tools work for published/external library data and file metadata:
| Task | Tool |
|---|---|
| Search published DS components | mcp__figma__search_design_system |
| Get component design context | mcp__figma__get_design_context with nodeId |
| Take screenshot | mcp__figma__get_screenshot |
| Get file structure (pages) | mcp__figma__get_metadata — avoid on root node (0:1) for large files, it will overflow. Use on specific page nodeIds or use use_figma instead. |
| Get published variables | mcp__figma__get_variable_defs — may fail with "select a layer first" error. Fall back to use_figma Plugin API. |
| Task | Tool |
|---|---|
| Create/update variables | mcp__figma__use_figma with Plugin API code that loops through tokens |
| Create/modify components | mcp__figma__use_figma with Plugin API code |
| Build full designs | mcp__figma__use_figma |
| Generate from description | mcp__figma__generate_figma_design |
| Task | Approach |
|---|---|
| Read token files | Read tool on discovered/configured paths |
| Read CSS variables | Read tool, parse :root and .dark blocks |
| Read Tailwind config | Read tool, extract theme.extend |
| Read component code | Read tool on component paths |
| Search for components | Glob pattern on component directories |
When invoked, run this discovery sequence before dispatching to a workflow:
{current-directory}/.figma-suite/config.json — project-level workspace<HOME>/.claude/figma-suite/*/config.json — global workspace where projectPath matches the current directorytokenSource: "auto", scan for token files in the codebasetailwind.config.*, global.css, theme.* to understand the styling systemsrc/components/ui, src/components, components/)design-rules.md from the workspace folder (see config-schema.md)These apply whenever creating or modifying Figma components — in build-library, design, or any ad-hoc component work. For Plugin API implementation details, see build-library.md and component-contracts.md.
Every rule below MUST be followed for every qualifying element. If you decide a rule doesn't apply to a specific element (e.g., a decorative separator doesn't need a TEXT property), you MUST report it as an explicit exception with a reason. Silently skipping a binding or property is a bug — it produces components that look complete but are broken for consumers.
Every user-facing text layer in a component MUST have:
Show Description)When to skip: Internal layout helpers, decorative characters, or separators that consumers should never edit. Report each skip as an exception.
Example: Dialog has Title (text + Show Title) and Body (text + Show Body). This lets consumers create a title-only dialog by hiding the body.
Every nested component instance MUST have:
Show CTA, Show Icon)When to skip: Structural instances that are integral to the component's layout and should never be swapped (e.g., an internal spacer component). Report as exception.
Never use raw frames as content slots — only INSTANCE_SWAP properties.
Every fill, stroke, radius, padding (all 4 sides individually), gap, and font property MUST be bound to a variable. Walk every node and bind each property — do not rely on "looks correct" as a proxy for "is bound."
When to skip: One-off decorative values with no matching variable in the scale, gradient fills (which don't support variable binding), or image fills. Use the raw value and report as exception.
Bubble up the most-used child properties to the parent level. If Dialog nests a Button, expose CTA Label on the Dialog itself so consumers don't have to drill into the Button instance.
Parent components MUST use Hug Contents so they adapt when children resize, get hidden, or get swapped. Only use Fixed height when a design token defines it (e.g., button heights).
Every text layer MUST have a Text Style applied via setTextStyleIdAsync(). Text Styles bind all 4 properties (family, size, weight, line-height) as one unit. TextStyle.setBoundVariable() does NOT work in headless use_figma — create Text Styles with raw values during token sync; variable binding on styles must be done interactively in the Figma UI after the build.
When to skip: If no matching text style exists, set raw font properties and report as exception.
After creating or modifying any component, you MUST run the programmatic verification script (see component-contracts.md). This catches unbound properties, missing component properties, and unapplied text styles. Fix all violations before proceeding. Report all exceptions to the user.
Tier 1 (primitives) → Tier 2 (interactive) → Tier 3 (containers) → Tier 4 (overlays). Never build a component before its children exist.
Works in any setup: single file, separate library file(s), no library yet, or adding to an existing library. The config supports multiple libraries and multiple design files — see config-schema.md. The only difference is where components are created and whether publishing is needed after.
Code and Figma components are not always 1:1. Setup generates a component-mapping.generated.md (relative within workspace) that tracks the relationship:
This file is user-editable. All workflows respect it: build-library skips code-only, audit ignores diverged with documented reason, design uses the correct Figma component regardless of code structure.
During setup, the user picks a naming preset that applies across all workflows:
figma-standard (default) — PascalCase, Title Case properties, Has/Show/Is booleanscode-first — camelCase properties matching code propscti — Category-Type-Item token structurethree-tier — Primitive → Semantic → Component token tierscustom — user-defined rules per aspectThe preset controls component names, property names, layer names, token separators, and boolean prefixes. See naming-conventions.md for full details.
For detailed guidance on specific topics. Only load these when actively needed — do not read all at once.
npx claudepluginhub robukh/figma-suite --plugin figma-suiteOrchestrates multi-phase Figma design system builds from code, creating variables, tokens, and component libraries with variant bindings and theming.
Automates design handoff from Figma to code: extracts tokens, maps components, detects drift, and generates implementation plans. Reduces handoff time from hours to minutes.
Generates Figma components or screens by compiling a CSpec into a scene graph and executing it via MCP. Use when the user asks to make, design, or build new UI in Figma.