Not “pixel-perfect”.
Provably pixel-accurate.

Every other Figma-to-code tool hands you a starting point and hopes. CONCRA hands you code with a score attached, names the Figma node when it is wrong, and fails your build rather than letting drift ship.

0.9978 mean layout SSIM 95% CI [0.9972, 0.9983] across 93 real screens
87/93 frames pass the gate 93.5%, Wilson CI [86.6, 97.0]
0.9924 worst single frame the number that actually matters

Figures measured at commit fa0dadd. The raw run is data/benchmark.json. Nothing on this page is typed in by hand.

The handoff nobody has fixed

Design-to-code is the most expensive, least reliable step in the delivery pipeline. It is done by hand, differently by every developer, and it drifts the moment the design changes.

The existing tools all produce a starting point that a human then rewrites. None produce a repeatable, updatable rail: a pipeline you re-run against an updated Figma and get a reviewable diff rather than a fresh pile of code. And not one of them publishes a substantiated accuracy benchmark. “98% pixel perfect” appears in marketing copy with no methodology, no dataset, and no definition of the metric.

CONCRA’s wedge is not generation. It is measurement.

How it works

  1. Extract

    Drives Figma directly and reads every frame, every node, every variable. No plugin to install, and no modification of Figma’s signed binary — that is circumvention, it breaks on every auto-update, and it fails enterprise review on sight.

  2. Normalise

    Everything becomes CIR, a layout algebra that projects onto flexbox, SwiftUI stacks, Compose, Flutter and Android without smuggling web assumptions into a native target. Constructs with no equivalent are recorded as lossy rather than quietly approximated.

  3. Generate

    Vanilla HTML/CSS/JS and React today; SwiftUI, Flutter and Android XML share the same layout algebra. Bound fills emit var(--token), never a hex code — the difference between output a team adopts and output they regenerate once and abandon.

  4. Verify

    Renders what it generated, diffs it against Figma’s own render of the same frame, and names the node behind every difference. Below threshold, the build fails. This is the part no competitor has.

  5. Re-run

    The design changes, you re-run, and your hand-written code survives. Generated regions are fenced; everything outside them is yours. Three-way merge against a snapshot of what was last generated, so a conflict means two people really did change the same thing.

The benchmark

Intervals are a percentile bootstrap over 10,000 seeded resamples for the means, and Wilson for the pass rate. Neither can report a value the data does not support: a t-interval on a score capped at 1.0 routinely claims a mean better than identical, and the normal approximation claims certainty from a perfect small sample. Measured on a real production design file — Momentum Bakari, 10 pages and 325 screens — not on a demo built to score well. 93 screens carry a reference render and are measured below.

Layout SSIM

mean0.9978
95% CI0.9972 – 0.9983
median0.9994
10th percentile0.9935
worst0.9924
best1.0000

Gaussian-blurred SSIM. Separates “the layout is wrong” from “the content differs”, which are not the same problem and should not share a number.

Detail SSIM

mean0.9625
95% CI0.9560 – 0.9688
median0.9702
worst0.8409

Unblurred. Lower than layout by construction: two rendering engines never rasterise text identically, and any tool claiming otherwise is not measuring.

Structural

nodes compared6685
nodes off1186
min coverage100.0%

Generated DOM boxes against Figma’s own geometry. No image diff can name a node; this can, and it reports where an error was introduced rather than every element that inherited it.

Every frame, worst first

Published in full rather than as an average, because an average hides the frame that would have embarrassed us.

FrameLayoutDetailCoverage
Full Stack prototype / What is live now0.00000.00000.0%unverifiable
Bakari UI kit0.00000.00000.0%unverifiable
Mobile / Ideator / Capture Step 2 / Selected0.99240.9419100.0%pass
Mobile / Ideator / Capture Step 3 / File rejected0.99250.9248100.0%pass
Mobile / All / Capability guide / Loaded0.99290.9455100.0%pass
Mobile / All / Capability guide / Read expanded0.99320.9454100.0%pass
Mobile / Ideator / Capture Step 3 / Empty0.99330.9485100.0%pass
Mobile / Ideator / My work / Discard confirm0.99330.9489100.0%pass
Mobile / Ideator / Capture Step 1 / Valid0.99330.9295100.0%pass
Mobile / Ideator / Capture Step 1 / Saved0.99340.9339100.0%pass
Mobile / Ideator / Capture Step 1 / Save failed0.99340.9350100.0%pass
Mobile / Ideator / Capture Step 3 / Attached0.99350.9358100.0%pass
Mobile / Ideator / My work / Drafts0.99360.9453100.0%pass
Mobile / Ideator / Finished / Signal error0.99400.9360100.0%pass
Mobile / Ideator / Capture Step 2 / Error0.99400.9523100.0%pass
Mobile / Ideator / Finished / Signal loading0.99400.9404100.0%pass
Mobile / Ideator / Finished / No match0.99400.9398100.0%pass
Mobile / Ideator / Capture Step 1 / Empty0.99410.9534100.0%pass
Mobile / Ideator / Capture Step 1 / Below minimum0.99410.9544100.0%pass
Mobile / Ideator / Finished / One match0.99410.9371100.0%pass
Mobile / Ideator / Capture Step 3 / In production branch0.99440.9555100.0%pass
Mobile / Ideator / Capture Step 2 / Loading0.99450.9532100.0%pass
Mobile / Ideator / Capture Step 2 / Empty0.99460.9438100.0%pass
Mobile / Ideator / Capture Step 2 / Resumed0.99510.9507100.0%pass
Web / All / Explore / Error0.99520.9773100.0%pass
Mobile / Ideator / Finished / Three matches0.99550.9523100.0%pass
Mobile / Executive / Portfolio / Empty0.99600.9558100.0%pass
Mobile / All / Explore / Filtered empty0.99640.9722100.0%pass
Mobile / All / Explore / Filters applied0.99660.9455100.0%pass
Mobile / Executive / Portfolio / Error0.99660.9704100.0%pass
Mobile / All / Explore / Empty0.99670.9768100.0%pass
Mobile / All / Explore / Error0.99680.9769100.0%pass
Mobile / All / Capture Step 2 / Guide open0.99680.9628100.0%pass
Mobile / All / Explore / Filters expanded0.99730.9734100.0%pass
Mobile / All / Initiative / As found0.99730.9533100.0%pass
Mobile / Executive / Portfolio / Loaded0.99740.9657100.0%pass
Mobile / All / Explore / Loading0.99740.9801100.0%pass
Mobile / All / Initiative / Merged0.99750.9573100.0%pass
Mobile / All / Initiative / Three share the problem0.99750.9557100.0%pass
Mobile / All / Explore / Loaded0.99750.9463100.0%pass
Mobile / All / Initiative / Comments0.99780.9481100.0%pass
Web / All / Explore / Page 20.99810.9478100.0%pass
Mobile / Executive / Portfolio / Figure opened0.99820.9702100.0%pass
Mobile / Executive / Portfolio / Loading0.99840.9871100.0%pass
Bakari / Project context0.99900.9231100.0%pass
Web / Executive / Portfolio / Error0.99940.9953100.0%pass
Web / Executive / Portfolio / Loaded0.99940.9745100.0%pass
Web / All / Explore / Loaded0.99940.9565100.0%pass
Web / Executive / Portfolio / Loading0.99960.9971100.0%pass
Web / All / Explore / Multi-select open0.99960.9657100.0%pass
Bakari · Portfolio0.99960.8409100.0%warn
Web / Executive / Portfolio / Empty0.99960.9854100.0%pass
Web / Executive / Portfolio / Figure opened0.99970.9914100.0%pass
Web / AI lead / Merge / Ready0.99990.9859100.0%pass
Production system / As-is reference0.99990.9645100.0%pass
Web / AI lead / Merge / Reason required0.99990.9904100.0%pass
Web / AI lead / Merge / Choose target0.99990.9904100.0%pass
Web / AI lead / Merge / Refused, already merged0.99990.9938100.0%pass
The question set / What you sent us, read back0.99990.9562100.0%pass
Web / Ideator / Capture Step 3 / Empty1.00000.9891100.0%pass
Web / Ideator / Capture Step 3 / In production branch1.00000.9897100.0%pass
Bakari · Explore1.00000.8647100.0%warn
Bakari · Joining an initiative1.00000.8848100.0%warn
Web / All / Explore / Filtered empty1.00000.9871100.0%pass
Bakari · Merging a duplicate1.00000.8692100.0%warn
Web / Ideator / My work / Drafts1.00000.9936100.0%pass
— PAGE TITLE —1.00000.9013100.0%pass
Web / All / Explore / Empty1.00000.9945100.0%pass
Bakari · The capability guide1.00000.9053100.0%pass
Web / Ideator / My work / Discard confirm1.00000.9922100.0%pass
Web / Ideator / Finished / Three matches1.00000.9890100.0%pass
Web / Ideator / Capture Step 1 / Save failed1.00000.9899100.0%pass
Web / Ideator / Capture Step 1 / Saved1.00000.9897100.0%pass
Web / Ideator / Finished / One match1.00000.9888100.0%pass
Web / Ideator / Finished / No match1.00000.9902100.0%pass
Web / Ideator / Capture Step 2 / Error1.00000.9937100.0%pass
Web / Ideator / Capture Step 2 / Loading1.00000.9941100.0%pass
Web / Ideator / Capture Step 2 / Empty1.00000.9903100.0%pass
Web / Ideator / Capture Step 1 / Empty1.00000.9956100.0%pass
Web / All / Initiative / Merged1.00000.9848100.0%pass
Web / All / Initiative / Comments1.00000.9841100.0%pass
Web / All / Explore / Filters applied1.00000.9849100.0%pass
Web / AI lead / Initiative / Merge available1.00000.9871100.0%pass
Web / All / Capability guide / Explore not answering1.00000.9762100.0%pass
Web / All / Initiative / Three share the problem1.00000.9884100.0%pass
Web / All / Capability guide / Read expanded1.00000.9740100.0%pass
Web / All / Capability guide / Loaded1.00000.9738100.0%pass
Web / All / Explore / Search active1.00000.9872100.0%pass
Web / All / Initiative / As found1.00000.9891100.0%pass
Personas / Who needs to see what1.00000.9472100.0%pass
Web / All / Capture Step 2 / Guide open1.00000.9935100.0%pass
Web / AI lead / Duplicates avoided1.00000.9933100.0%pass
Web / All / Explore / Loading1.00000.9956100.0%pass

What CONCRA does not claim

A ten-nines accuracy claim is not achievable and, more importantly, not measurable. On a 1440×900 frame that would mean fewer than 0.0001 pixels may differ; one antialiased glyph edge breaks it. There is also no oracle: Figma’s renderer and a browser’s disagree on text by construction, and neither is wrong.

Every one of those limits is in the tool’s own output, not just on this page.

Targets

Vanilla HTML + CSS + JS

Auto-verified. The reference target.

React + JSX

Auto-verified. Component sets become one component with variants, not N copies.

SwiftUI

Codegen plus an opt-in macOS verification job.

Flutter

Golden tests in a pinned Linux container.

Android XML

Roborazzi on a plain JVM. No device, no emulator.

Design tokens

DTCG, CSS custom properties, and Style Dictionary transforms.

Use it from your agent

CONCRA ships an MCP server, so Claude Code, Cursor or your own tooling can drive the whole pipeline. One concra_load_file spends the Figma quota once; every call after that is local and free.

claude mcp add concra -- concra mcp serve

That quota arithmetic is the point. Figma’s own MCP server is capped at a few hundred reads a day and hands back opinionated React, not data.

Pricing

Team

$89/seat/month

  • Every target
  • Fidelity gate in CI
  • Design tokens and the MCP server
  • The update rail

Enterprise

Self-hosted

  • Runs on your machines, in your session
  • Your designs never leave your network
  • Calibration against your own corpus
  • Support and onboarding

The field sits at $24–$100 per seat. CONCRA sits near the top of it, because a measured guarantee is worth more than an unmeasured one.

See it against your own file

The interesting demo is not ours. Point CONCRA at a design your team is arguing about and read the report.

Book a demo