A
Cursor logoCursorFrontend / UI from designs

Cursor Frontend Figma Pipeline

Luca Marenco@lucadesigns
89.0Overall score

Figma MCP turns design frames into pixel-accurate components, and an accessibility reviewer subagent enforces WCAG before merge. Visual-regression on commit catches unintended UI drift.

89.0Score
1.2kVotes
5Components
5hUpdated

Install this build

Export
terminal
npx setuproll add cursor-frontend-figma

Components

Model

  • Claude Sonnet 4.6

MCP servers

  • figma
  • playwright
  • github

Subagents

  • agent-mode-worker
  • a11y-reviewer

Hooks

  • on-save: format
  • pre-commit: visual-regression

Rules

  • Match Figma tokens exactly
  • Every component meets WCAG AA
  • Storybook story per component
Workflow

I make Cursor build my Figma, pixel for pixel, or it does not merge

How I wired Figma, Playwright, and an accessibility reviewer into Cursor so the agent ships components that actually match the design.

lucadesigns8 min readJun 2026

I have a thing about handoff. You spend two days getting a card just right in Figma, the radius, the shadow that is barely there, the way the title sits exactly 12px off the image, and then it gets built and the shadow is gone and the radius is 8 instead of 10 and nobody but you can tell. For years that 1px was my problem to chase. Now I make the agent chase it. This is the Cursor setup I use to turn frames into front end that actually matches, and refuses to merge when it does not.

The build, plainly: Cursor running Claude Sonnet 4.6 in agent mode, with three MCP servers (Figma, Playwright, GitHub), two subagents (an agent-mode worker that builds and an a11y-reviewer that gates merges), and two hooks: format on save, visual-regression on commit. It is not a huge rig. It is just opinionated in the right places.

Figma is the source of truth, so the agent reads it

The whole thing falls apart if the agent guesses. The Figma MCP server is what stops the guessing. Cursor can pull the actual node: the fills, the auto-layout gaps, the text styles, the exact token names. I paste a frame link, the agent reads the structure, and it builds against real values instead of vibes. Here is my MCP config. It lives in .cursor/mcp.json at the project root.

.cursor/mcp.json
{
  "mcpServers": {
    "figma": {
      "command": "npx",
      "args": ["-y", "figma-developer-mcp", "--stdio"],
      "env": { "FIGMA_API_KEY": "${FIGMA_API_KEY}" }
    },
    "playwright": {
      "command": "npx",
      "args": ["-y", "@playwright/mcp@latest", "--browser", "chromium"]
    },
    "github": {
      "url": "https://api.githubcopilot.com/mcp/"
    }
  }
}
Keep the Figma key in env
Do not paste your Figma personal access token straight into the config. The ${FIGMA_API_KEY} reference reads it from your shell, so the file is safe to commit and your token never lands in git history. I learned this the boring way after rotating a leaked token at 11pm.

The rules file does the nagging so I do not have to

Cursor reads .mdc rule files automatically based on which files you touch. This is the single highest-leverage part of the setup. My rules are short and mean. No essays. The agent does not need my design philosophy, it needs the 4px scale and a hard no on inventing colors.

.cursor/rules/frontend.mdc
---
description: Frontend rules for turning Figma frames into shipped components
globs:
  - "src/components/**/*.tsx"
  - "src/**/*.stories.tsx"
alwaysApply: true
---

# How we build UI here

- Match the Figma file as the source of truth. Read tokens from
  src/styles/tokens.css, never eyeball a hex. If a value is not a
  token, stop and ask before hardcoding it.
- Spacing is the 4px scale only: 4, 8, 12, 16, 24, 32, 48, 64.
  No 13px, no 17px, no "looks about right".
- Every interactive element meets WCAG AA: visible focus ring,
  4.5:1 text contrast, a real label or aria-label. No div soup
  with onClick. Use a button.
- One Storybook story per component, with the variants that exist
  in Figma (default, hover, disabled, loading). If Figma has it,
  the story has it.
- Tailwind utilities for layout, CSS variables for theme. Do not
  invent a new color. Do not add a UI dependency to get one shadow.

That spacing rule alone killed about half of my old review comments. The agent used to drop a 13px gap because the screenshot kind of looked like 13px. Now it snaps to the scale or it asks. Much calmer.

An accessibility reviewer that can actually say no

Here is my real opinion: most AI-built UI is inaccessible garbage. Divs with click handlers, focus rings ripped out because they looked ugly, contrast that fails on the placeholder text. So I gave the build a second agent whose only job is to fail my first agent. It does not build anything. It reads one component and reports.

.cursor/agents/a11y-reviewer.md
# a11y-reviewer

You review a single React component before it is allowed to merge.
You do not write features. You only check and report.

## Checklist (fail loudly on any miss)
1. Color contrast >= 4.5:1 for text, 3:1 for large text and icons.
   Pull the actual token values, do not assume.
2. Keyboard path: can you reach and operate it with Tab + Enter +
   Space? Is the focus ring visible against the background?
3. Semantics: button vs link vs div used correctly. Headings in
   order. Form fields have associated labels.
4. State: aria-disabled / aria-expanded / aria-current set where
   the visual state implies them.

## Output
A short pass/fail per item, then the exact diff to fix the fails.
End with one line: "AA: pass" or "AA: fail (N issues)".
a11y-reviewer — Cursor agent panel
You
Review src/components/PricingCard.tsx against AA before I merge.
Agent
1. Contrast: pass (text #1A1A2E on #FFFFFF = 16.1:1). 2. Keyboard: FAIL. The 'Choose plan' button is a <div onClick>. Not reachable by Tab. 3. Semantics: FAIL, same element. 4. State: the selected plan has no aria-current.
Agent
Fix: swap the div for <button type="button" aria-current={selected ? 'true' : undefined}> and keep the focus-visible ring from tokens.css. Diff below. AA: fail (2 issues)
The reviewer pass on a pricing card. It found a real focus-ring bug I would have shipped.
The reviewer is not optional
Early on I treated the a11y pass as a nice-to-have and skipped it when I was in a hurry. Three of those rushed components shipped with broken keyboard nav. Now the pre-commit hook will not let a component through without an AA: pass line in the agent log. Annoying on purpose.

What a real session looks like

Two hooks run without me thinking about it: on save, the formatter cleans the file; on commit, Playwright snaps the rendered component and diffs it against the baseline. If a shadow changed or a gap drifted, the commit stops. That visual-regression step is the thing that finally let me trust the agent on the small stuff.

zsh — frontend
build a component straight from a Figma frame
$git commit -m 'feat: pricing card from figma'
running on-save format... done
pre-commit: visual-regression (playwright)
PricingCard/default ........ match
PricingCard/hover .......... DIFF 0.8% (shadow blur 12 -> 8)
caught it. the agent used the wrong shadow token
commit blocked: 1 visual diff over threshold
$cursor: fix hover shadow to use --shadow-sm per figma
patched PricingCard.tsx, re-running...
PricingCard/hover .......... match
AA: pass
[main 4f1c9ab] feat: pricing card from figma
$

The numbers, and what they cost me

I am not going to pretend it is magic. Sonnet 4.6 in agent mode is fast and cheap enough that I leave it running, and the gating is what makes the speed safe. Rough averages from my last month of work:

MetricValueWhat it means
Avg response1.2sFast enough to stay in flow
Cost / task$0.24I do not watch the meter anymore
Pass rate83%1 in 6 still needs a real fix from me
Build score89A-tier on Setuproll, and earned

That 83% is honest. The agent nails layout and tokens. Where it still loses is taste calls: when two designs are technically valid and one just feels better. That part is still my job, which is fine. I did not want a robot that designs. I wanted one that builds exactly what I designed.

Steal these

  • Put your design tokens in one file and forbid the agent from hardcoding values. This fixes more than any prompt trick.
  • Make a second agent whose only job is to reject the first one. Building and reviewing should not be the same context.
  • Visual regression on commit. If you ship UI, this is the seatbelt.
  • Keep rules short. Three crisp constraints beat a 600-word style guide the model skims.
Cursor AI Tutorial - My Personal Tips & Tricks28:05
Cursor AI Tutorial - My Personal Tips & Tricks· Volo Builds
Cursor Docs — Agent, Rules, MCP & CLIThe official reference for .mdc rule files, agent mode, and wiring MCP servers. Start here if you copy my config.cursor.comPatrickJS/awesome-cursorrulesA pile of community .cursorrules files. Good for stealing patterns, but trim them hard. Most are way too long.github.com/PatrickJS30k+The Best MCP Servers for Developers in 2026Setup notes for the Figma, GitHub and Context7 MCP servers, including the env-var pattern I use for the Figma key.builder.io

If you want the whole thing wired the way I run it, rules, MCP config, both agents, and the two hooks, grab it in one line: npx setuproll add cursor-frontend-figma. Then point it at a Figma frame and watch it sweat the 1px so you do not have to.

0 Reviews

Your rating
Sign in to post

Loading discussion...