Every hardcoded value now traces to a Figma node, and "looks right" is no longer accepted as proof.
We packaged the fix as a reusable Claude Code skill, implementing-figma-designs. It turned Figma-to-code from a "build it, then eyeball it against the PNG for three correction rounds" loop into a staged extract-then-prove protocol.
The Problem
An LLM handed a Figma frame will happily invent a 1px solid #91A3B3 border, size a 24px icon at 28px, and guess the icon→text gap — because a faint border and an off-by-4px value both look correct in a screenshot, so a screenshot-based "does it match?" check passes while the running DOM is wrong.
How we solved it
-
Screenshots are for layout only — never for values. Every color/size/spacing/radius must come from the Figma MCP (
get_variable_defs/get_metadata/get_design_context) per node, or be explicitly flagged as off-system. No value is read off the PNG. -
Staged query protocol so ground truth is extracted before any product code:
orient → classify nodes → confirm component mappings → triangulate code+tokens+geometry → implement. -
Tokens beat raw hex. Whatever
get_design_contextemits as#EE0F51gets reconciled back to the project's design token; anything with no token is raised to the designer, not silently hardcoded. -
Real interactive components, never the flattened
<img>that the MCP emits for un-wired toggles/inputs — every interactive node is mapped to a confirmed repo component via a human gate. -
Evidence-on-claim verification (the key move): the running implementation is driven in a real browser (chrome-devtools MCP), and each suspect value is confirmed with
getComputedStyleagainst the Figma node value. The screenshot tells you that something is off; the computed style tells you what. -
The trade-off: verification is slower and chattier than a glance at a PNG — more tool calls, a human confirmation per interactive component — but it's the only thing that catches a design-system specificity loss (an
sxoverride that loses to.MuiOutlinedInput-notchedOutlineand silently keeps the wrong border while nothing errors).
Before → After
# BEFORE — value read off the screenshot, "looks right" == done
- <Icon size={28} /> // guessed; node is actually 24
- border: '1px solid #91A3B3' // invented; frame has no border
- // verification: screenshot looks close → PASS (DOM still wrong)
# AFTER — value traced to a node, proven in the DOM
+ // get_metadata(node) -> width/height = 24 → <Icon size={24} />
+ // get_variable_defs(node) -> no border token → frame has NO border → omit
+ // Stage 6, in a real browser:
+ getComputedStyle($icon).width // "24px" ✔ matches node
+ getComputedStyle($toolbar).borderWidth // "0px" ✔ matches frame
+ // PASS only when computed CSS == node value, per element
The protocol, end to end
Figma frame URL
│
▼
[0] resolve to a concrete node ──► [1] orient (PNG = structure only)
│ │
▼ ▼
[2] classify nodes ──► [3] confirm component mappings (human gate)
│
▼
[4] triangulate: get_design_context + get_variable_defs + get_metadata
│ └─ raw hex/px → project token (or flag off-system)
▼
[5] implement from tokens + geometry + real components
│
▼
[6] VERIFY in a real browser: getComputedStyle(el) == node value ?
PASS only per-element, with evidence — not "the PNG looks right"
Results
- The three defects that slipped past a human PNG-review on the origin ticket (invented border, 28px-vs-24px icon, guessed gap) are now caught mechanically at Stage 6 instead of over several by-hand correction rounds.
- Screenshot-only sign-off is explicitly disallowed — a node isn't "done" until computed CSS is proven to equal the node value.
- Reusable across the team: it's a versioned skill, auto-invoked when
planning-dev-taskhands off a Figma-linked PRD, and its verification leg (checking-figma-fidelity) plugs into our test-plan runner as a visualT-<n>.
Want to try it?! Ping me and I'll send the skill over
Top comments (0)