figma-to-code
Use whenever the user pastes or references a figma.com / Figma design link or node and wants code to match it — whether that means building something new OR fixing/adjusting existing code to match the design. This includes small targeted edits like "fix the text color to match Figma", "make the spacing match the design", "adjust the font to match Figma", "this should look like Figma", as well as full builds like "code this design", "implement this section from Figma", "convert Figma to HTML/React/Vue", "build this Figma page". Also covers any request that compares existing code against a Figma design and corrects the difference (color, spacing, typography, layout, icons). Multiple Figma URLs in one prompt is a strong signal. The skill reads exact styles and design variables from the Figma MCP, downloads images/SVG icons, then verifies the result in the browser with Playwright and an objective pixel-diff loop until it matches. Triggers in any language, including Vietnamese ("sửa cho giống figma", "khớp với figma", "đúng như figma", "sửa màu/spacing/font theo figma"). Strongly prefer this skill over guessing styles from a screenshot — the Figma MCP returns authoritative measurements.
Works with
---
name: figma-to-code
description: Use whenever the user pastes or references a figma.com / Figma design link or node and wants code to match it — whether that means building something new OR fixing/adjusting existing code to match the design. This includes small targeted edits like "fix the text color to match Figma", "make the spacing match the design", "adjust the font to match Figma", "this should look like Figma", as well as full builds like "code this design", "implement this section from Figma", "convert Figma to HTML/React/Vue", "build this Figma page". Also covers any request that compares existing code against a Figma design and corrects the difference (color, spacing, typography, layout, icons). Multiple Figma URLs in one prompt is a strong signal. The skill reads exact styles and design variables from the Figma MCP, downloads images/SVG icons, then verifies the result in the browser with Playwright and an objective pixel-diff loop until it matches. Triggers in any language, including Vietnamese ("sửa cho giống figma", "khớp với figma", "đúng như figma", "sửa màu/spacing/font theo figma"). Strongly prefer this skill over guessing styles from a screenshot — the Figma MCP returns authoritative measurements.
license: MIT
---
# Figma to Code
Turn a Figma node into production-ready frontend code (HTML/CSS, React, Vue, Svelte, or any framework), then verify it visually against the source design and iterate until the rendered output is indistinguishable from Figma at the same viewport.
## Why this skill exists
Eyeballing pixel values from a Figma screenshot is wasteful and inaccurate. Figma already knows the exact padding, gap, font, color, design-variable token, and absolute position of every node — so does its image export. This skill makes you read those values, reuse the design system's variables, download the real assets, and close the loop with a browser screenshot diff instead of "looks about right".
## Required MCPs (verify before starting)
This skill assumes both servers are reachable. If either is missing, stop and ask the user to enable it.
| Purpose | Tool |
|---|---|
| Read Figma node tree, styles, layout, variables | `figma_get_figma_data` |
| Export images & SVG icons from Figma | `figma_download_figma_images` |
| Render and screenshot the result | `playwright_browser_*` |
> Tool names above are the real callable names in this environment. Some Figma MCP builds expose extra calls for variables/styles; if `figma_get_figma_data` already returns `boundVariables`/`styles`, you do not need them.
## Two modes: full build vs targeted fix
Decide which mode you're in before touching the workflow — they share extraction but diverge on scope.
- **Full build** — "implement / convert / build this design". Run the entire Core workflow below.
- **Targeted fix** — "fix the text color to match Figma", "make the spacing match", "sửa màu/font/spacing cho giống figma". The code already exists; the user wants one category of property corrected to match the design. **Do NOT rebuild the section.** Instead:
1. Parse every Figma URL/node in the prompt (step 1). Multiple URLs usually map to multiple sections/elements the user wants fixed — handle each.
2. Extract **only the relevant property** for the referenced nodes (step 3) — e.g. for "sửa màu text", pull the text nodes' fill colors (and their bound color variables, if any).
3. Locate the matching elements in the existing code (read the files; don't guess which selector).
4. Apply the minimal edit — change only that property (color/spacing/font), referencing a token when the design binds one.
5. Verify just that property against Figma (visual check or the pixel-diff loop on the affected element). Don't re-diff the whole page.
Skip the asset-download, token-scaffolding, and full-markup steps unless the fix genuinely needs them.
## Core workflow
Always run the steps in this order. Each step references a dedicated guide — read it only when you reach that step.
1. **Parse input → identify `fileKey` and `nodeId`.**
- Figma URLs look like `figma.com/(file|design)/<fileKey>/<slug>?node-id=<nodeId>`. The `node-id` arrives as `1234-5678` in the URL but must be normalized to `1234:5678` for the MCP call.
- If the user gave only a screenshot, ask for the Figma link before continuing. Do not guess.
2. **Confirm output target & framework.** See "Output target" below.
- Ask once which file/framework should receive the code if it is not obvious from the project, then proceed.
3. **Extract the design tree AND the design system.** See `references/figma-extraction.md`.
- Call `figma_get_figma_data` with the `fileKey` and `nodeId`.
- Inventory the result into five buckets: layout containers, text nodes, image fills (`imageRef`/`gifRef`), pure vectors (icons → SVG candidates), and **bound design variables** (color/spacing/radius/typography tokens).
- Record the node's exported size, padding, gap, primary axis, alignment, background, border-radius, effects.
- Capture the **fonts** in use (family, weights, styles) so you can load them before rendering — a wrong font fallback is the #1 cause of a failed diff.
4. **Establish design tokens before writing values.** See `references/figma-tokens.md`.
- If the node has bound variables (Figma Variables), mirror them as CSS custom properties / framework theme tokens **once**, then reference the token instead of repeating the raw px/hex everywhere.
- If there are no variables, still infer a small scale from repeated values (spacing 4/8/12/16/24…, repeated colors) and define tokens — this is what makes the output feel "designed", not hardcoded.
- Pixel accuracy still wins: a token must resolve to the exact value Figma reports.
5. **Download every asset.** See `references/asset-download.md`.
- PNG/GIF for raster fills (anything with `imageRef` or `gifRef`).
- SVG for any vector that behaves like an icon (small, monochrome or 2-tone, sits inline with text, repeats across the design).
- Inline as CSS `clip-path`/`border-radius` for shapes Figma drew as vectors but that are really just rounded boxes, blobs, or geometric cutouts (see `references/figma-to-css.md`).
- Save into the project's asset folder using the project's existing naming convention; never dump into `/tmp` for code that will be committed.
6. **Generate the markup + styles.** See `references/figma-to-css.md`.
- Map Figma Auto Layout → Flexbox (or Grid for true grid layouts).
- Use the exact pixel values Figma reports for `padding`, `gap`, `width`, `height`, font-size, line-height, letter-spacing — referencing the tokens from step 4 where they apply.
- Convert Figma color to `#rrggbb` or `rgba()` preserving opacity.
- Use `clip-path` for non-rectangular masks before reaching for a PNG.
- Load the design fonts (web fonts or `@font-face`) before rendering.
7. **Handle responsive / multiple frames.** See `references/figma-to-css.md` (responsive section).
- If the user provides desktop + tablet + mobile frames, extract each, find the breakpoints, and write media queries / container queries that interpolate between the fixed designs.
- If only one frame exists, build to that width and ask whether responsive behavior is needed before inventing breakpoints.
8. **Render in browser.** See `references/visual-verification.md`.
- Component/section → write a temporary standalone HTML at `/tmp/figma-verify/<slug>.html`, open with `file://` in Playwright.
- Framework component → run the project's dev server (`npm run dev` / `pnpm dev` / etc.) and navigate to the local URL for that component/route.
- Resize the viewport to **exactly** the width of the Figma frame before screenshotting.
9. **Objective visual diff against the Figma export.** See `references/pixel-diff.md`.
- Export the same node from Figma as PNG via `figma_download_figma_images` at `pngScale: 2`, save to `/tmp/figma-verify/<slug>-figma.png`.
- Take a Playwright element screenshot at the same scale into `/tmp/figma-verify/<slug>-rendered.png`.
- Run `scripts/diff.mjs` to get a **diff percentage** and a highlighted diff image — don't rely on eyeballing.
- Open the diff image with `Read` to see *where* the magenta is, then translate the largest mismatch region into one targeted CSS change.
10. **Iterate until match (hard loop).** See "Iterate-until-match" below.
- Re-render → re-screenshot → re-run `diff.mjs`. The `diffPercent` **must trend down each round**.
- Keep going until the element passes the threshold in `pixel-diff.md` (≤0.5% clean pass, or 0.5–2% where the remaining magenta is only on text edges / photo speckle).
- Do not declare success on a "looks close" — declare it on a measured number plus a clean diff image.
## Iterate-until-match
The whole point of this skill is closing the loop on a **measured** number, not stopping at "looks close". After the first render, every round must be driven by `scripts/diff.mjs`:
1. Render → element screenshot → run `diff.mjs --json` → record `diffPercent`.
2. Open the diff image. Find the **single largest magenta region**.
3. Apply **one** targeted fix for that region (change one rule, not five — otherwise you can't tell what worked).
4. Re-render, re-diff. `diffPercent` must go **down**. If it went up, your last change was wrong — revert it.
5. Repeat until the element **passes the threshold** in `references/pixel-diff.md`:
- **≤ 0.5%** → clean pass.
- **0.5–2%** → open the diff image; pass only if the remaining magenta is on text anti-aliasing edges or photo re-encode speckle, never on layout/spacing edges.
- **> 2%** → keep iterating; there is a real structural difference.
### When you may stop before 0%
True 0% is usually impossible — OS font rasterization and sub-pixel rendering differ from Figma's renderer, which is exactly why `diff.mjs` ignores anti-aliasing. You stop when **all of these hold**:
- `diffPercent` is within the pass band above, AND
- the diff image shows no magenta on layout edges, spacing, color blocks, or icons (only on glyph edges / photo speckle), AND
- the difference that remains is provably not CSS-fixable (e.g., a missing licensed font — flag it to the user rather than faking it).
### Genuine blockers (flag, don't fake)
Stop and tell the user instead of hacking around it when the residual diff is rooted in:
- A **missing font/license** — substituting a lookalike to make the number drop is a lie. Name the family + weights needed.
- A Figma effect CSS can't reproduce 1:1 (certain blend modes, noise textures) — get as close as CSS allows, then flag the gap.
- A **plateau**: if `diffPercent` stops improving across 3 rounds and is still failing, re-read the Figma data for that subnode — you're likely applying the wrong source value, not the wrong CSS.
Never loosen `--threshold` or shrink the compared region just to make a failing diff report "pass".
**Image vs SVG icon vs CSS shape — pick one:**
| Looks like | Pick | Why |
|---|---|---|
| Photo, illustration, gradient mesh | PNG/JPG | Raster fidelity matters |
| Animated visual | GIF (`gifRef`) | Static export loses motion |
| Small flat glyph, currentColor-recolorable, repeats | SVG icon | Crisp at all sizes, themeable |
| Rounded rectangle, circle, blob, ribbon, diagonal cut | CSS (`border-radius`, `clip-path`) | No HTTP request, scales perfectly |
| Complex 3D-ish shape Figma drew with many vectors | SVG (treat as image, embed `<svg>` or `<img>`) | Hand-coding clip-path is brittle |
**Hardcoded value vs token — pick one:**
| Situation | Pick |
|---|---|
| Node has a bound Figma Variable for the value | Reference the token (`var(--color-primary)`, theme key) |
| Value repeats 3+ times across the design | Define a token, then reference it |
| One-off optical nudge (`padding-top: 47px`) | Inline the raw value, comment why |
**Output target — pick one per task:**
| Context | Output |
|---|---|
| User says "build this Figma block first, I'll wire it later" | Standalone HTML+CSS under `/tmp/figma-verify/` until approved |
| User names a framework component/file | Edit that file in the framework's idioms (JSX/SFC/etc.) + the project's styling system (CSS modules, Tailwind, styled-components…) |
| Reusable component across many pages | Create a self-contained component with scoped styles + a tokens file |
| Plain static site | HTML file + linked stylesheet, fonts loaded via `<link>` or `@font-face` |
When in doubt, ask the user once which file/framework should receive the code, then proceed.
## Operating principles
- **Read Figma data before writing code.** Never invent a padding value if Figma can report it. The MCP call is cheap; reverse-engineering a number from a screenshot is not.
- **Reuse the design system, don't reinvent it.** If Figma binds a color to a variable, your code should reference a matching token, not a raw hex copied 30 times. This is what makes output match Figma's *intent*, not just its pixels.
- **Spatial accuracy beats class names.** A perfect Tailwind class string with wrong gap is a regression. Use the exact values from Figma; refactor naming later.
- **Verify per node, not per page.** Diffing a whole hero against Figma is noisy. Diff the headline, then the CTA, then the image — fix what's actually off.
- **Load the real fonts.** A font fallback shifts every metric. Confirm the design font is the *first* applied family before chasing spacing diffs.
- **Keep asset names traceable.** Include the Figma node id in the filename (e.g., `commitment-image-2481-7671.png`) so future you can find where it came from.
- **Stop downloading when CSS will do.** Every PNG you skip is bytes saved and scaling preserved.
- **Trust the data, not the eye.** If Figma says 24px gap and your eye says 22, write 24.
## Constraints
### MUST DO
- Normalize `node-id=1234-5678` from the URL to `1234:5678` before calling Figma MCP.
- Capture bound design variables and mirror them as tokens before hardcoding repeated values.
- Load the design's fonts before rendering and verifying.
- Save downloaded assets inside the project (a user-specified or conventional asset folder), not in `/tmp` for code that ships.
- Match the Playwright viewport to the Figma frame width before screenshotting.
- Export the Figma node as PNG and compare it side-by-side with the rendered screenshot via `scripts/diff.mjs`, not from memory.
- Iterate until the measured `diffPercent` passes the threshold in `references/pixel-diff.md`; drive each fix from the diff image.
- Honor existing project conventions (filename pattern, styling system, component structure).
### MUST NOT DO
- Estimate paddings, gaps, font sizes, or colors from a screenshot when Figma MCP can return them.
- Copy the same raw hex/px everywhere when the design clearly uses a shared token.
- Re-render a vector icon as a PNG export when it could be downloaded as SVG.
- Inline base64 images into HTML — always save to disk and reference by URL.
- Skip the visual verification step. The whole point of this skill is closing that loop.
- Invent responsive breakpoints when only a single frame was provided — ask first.
## Reference index
Load the relevant guide when you reach that step in the workflow:
| Step | Guide | Read when |
|---|---|---|
| Extract Figma data + fonts | `references/figma-extraction.md` | Step 3 |
| Mirror Figma Variables → tokens | `references/figma-tokens.md` | Step 4 |
| Download images & SVGs | `references/asset-download.md` | Step 5 |
| Map Figma → CSS, clip-path, responsive | `references/figma-to-css.md` | Steps 6–7 |
| Browser render & visual diff | `references/visual-verification.md` | Steps 8–9 |
| Objective pixel diff + thresholds | `references/pixel-diff.md` | Steps 9–10 |More Design Systems skills
stitch-design-taste
leonxlnx/taste-skill
Semantic Design System Skill for Google Stitch. Generates agent-friendly DESIGN.md files that enforce premium, anti-generic UI standards — strict typography, calibrated color, asymmetric layouts, perpetual micro-motion, and hardware-accelerated performance.
figma
heygen-com/hyperframes
Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.
image
coreyhaines31/marketingskills
When the user wants to create, generate, edit, or optimize images for marketing — blog heroes, social graphics, product mockups, profile banners, listing visuals, or brand assets. Also use when the user mentions 'AI image generation,' 'generate an image,' 'create a graphic,' 'product mockup,' 'hero image,' 'social media graphic,' 'banner image,' 'cover photo,' 'profile banner,' 'listing screenshot,' 'Flux,' 'Flux Kontext,' 'Midjourney,' 'DALL-E,' 'GPT Image,' 'ChatGPT Images,' 'Ideogram,' 'Gemini image,' 'Nano Banana,' 'Recraft,' 'Stable Diffusion,' 'Canva,' 'Figma,' 'image optimization,' 'compress images,' 'WebP,' or 'OG image.' Use this for general-purpose marketing image creation and optimization. For paid ad image creative and platform-specific ad specs, see ad-creative. For video production, see video.

