Figma to code: why the output is visually right and structurally wrong

Every generation of design-to-code tooling gets closer to pixel-accurate and no closer to usable, and the reason is structural rather than a matter of model quality. A frame encodes appearance. Code needs intent, and the intent was never in the file.

Updated July 27, 2026

What a frame actually contains

A Figma frame is a tree of shapes with positions, fills, strokes, text runs and layout constraints. That is a complete description of how something looks at one size. It is not a description of what anything is.

In the fileMust be inferred
StructureA group of rectangles and text at these coordinatesThat this group is a Card, and that it is the same Card used on nine other screens
ColourFill is #6b7280Whether that is muted text, a border, a disabled state or a placeholder
Spacing32px between these two elementsWhether 32 is a scale step, a one-off, or the result of someone nudging
ResponsivenessConstraints, and whatever breakpoint frames existWhat happens at every width between them
SemanticsText with a larger size and heavier weightWhether it is an h1, an h2, or styled text that is not a heading at all
What a converter can read, and what it has to guess.

Every row in the right column is a decision the converter has to make with no information. It will make each one plausibly and independently, which is why the output is simultaneously convincing at a glance and impossible to maintain.

A frame encodes appearance. Code needs identity and intent. The converter is not failing — the information was never in the file.

What generated code costs you

Accept the output as-is and four specific problems follow, all of which surface after the code is merged rather than while it is being reviewed.

  1. 1

    No component reuse

    The same card converted on five screens becomes five independent implementations. Nothing links them, so a change to the card is five changes, and someone will find only four.

  2. 2

    Literal values everywhere

    Converters emit #6b7280 because that is what the fill says. Your token layer is bypassed entirely, which means the design system you built is now decorative on those screens.

  3. 3

    Absolute or fragile layout

    Position data converts to positioning. It matches the frame at exactly the frame's width and degrades at every other one, and the degradation is worst on the devices you tested least.

  4. 4

    No semantics

    Large heavy text becomes a styled div. Screen readers get a page with no heading structure, keyboard users get no landmarks, and nobody notices until an audit.

The second one is the most consequential and the least visible in review. Once generated screens carry literal colour values, your codebase has two colour systems: the tokens, and whatever the design file said that day. A CI check that fails on hex outside the token file catches it at the door.

Mapping beats generation

The productive reframe is to stop asking the tool to write code and start telling it which code already exists. Figma's Code Connect does exactly this: it links a design component to your real code component, so Dev Mode shows the actual component and its props rather than generated CSS.

That changes the problem from generation to lookup, and lookup is a problem that can be correct.

GenerateMap
ProducesNew markup approximating the frameA reference to the component you already maintain
ReuseNone — every conversion is freshTotal, by construction
TokensBypassed; literals emittedPreserved; the component already uses them
AccessibilityWhatever the converter inferredWhatever your component already does
Setup costNoneOne mapping per component, maintained as components change
Fails whenAlways, slowlyA design uses something that does not exist in code yet
Two ways to get from a design file to code.

That last row is the honest cost, and it is a real one: mapping only works for components that exist. A genuinely new design still needs building. But that is the correct division of labour — a human or an agent builds the new component once, and every subsequent use is a reference rather than a regeneration.

The target of the mapping is worth being concrete about. A handoff is finished when the code side looks like this — named roles with real values — rather than like a list of hexes recovered from a frame:

Preview unavailable here. Browse complete kits in the kit gallery.

The naming-parity move

Underneath component mapping is a cheaper change that closes a surprising amount of the gap, and it needs no tooling at all: use the same names in both places.

Salesforce's SLDS 2 is the clearest published example. Its Figma library uses the same semantic styling-hook names as the CSS — the team's own examples are radius-border-4 and font-scale-4 — so designs map one-to-one to live code. Their stated goal is a shared vocabulary bridging design and development.

The effect is that a whole category of handoff bug stops existing. When a designer says font-scale-4 and a developer types font-scale-4, there is no translation step, so there is nowhere for meaning to leak. Compare that with a Figma style called "Heading / Large" mapping to a CSS variable called --text-2xl: every handoff is a lookup, and every lookup can go wrong.

MismatchedMatched
HandoffA translation step per propertyCopy the name
Review"Is that the right grey?" requires opening both toolsThe name is either right or it is not
An agent reading bothTwo vocabularies, no stated relationship, silent guessingOne vocabulary
Where naming mismatches cost you.

If you do one thing from this article, rename your Figma variables to match your CSS custom properties exactly. It costs an afternoon, needs no plugin, and removes a permanent tax on every handoff. Flat, lowercase, hyphenated names survive both tools — more on naming for portability.

When the design system lives in Figma

Plenty of teams have a thorough Figma library and a codebase that only partly reflects it. The instinct is to find a tool that closes the gap automatically. There is a cheaper move that works better.

A Figma library contains the decisions — the scale, the roles, the component set, the spacing rhythm. Those decisions transfer perfectly well as text, and text is the format both a developer and a coding agent can act on. Extracting them into a token file plus a written brief is a day of work and it makes every subsequent conversion unnecessary, because the code side now has the same information the design side does.

We sampled 299 DESIGN.md files written to carry exactly that information to AI agents, and most of them do not: 86% specify colours as raw hex with no semantic role, 76% state no prohibitions, 69% define no dark mode, and 44% state no concrete size value anywhere. A brief extracted from a real Figma library, done properly, beats almost all of them — you already have the numbers.

  1. 1

    Export the variables as tokens, with roles

    Not the raw palette. The roles: which colour is muted text, which is a border, which is a disabled state. If your Figma variables are named by hue, this is the moment to rename them by role in both places at once.

  2. 2

    Write down the scales as numbers

    Type sizes, spacing steps, radii. The library already contains these; the code side usually has a subset plus improvisation.

  3. 3

    Write down what the library refuses to do

    The prohibitions are in the library implicitly — no shadows anywhere, no weight above 600 — and they are the highest-value thing to make explicit, because they are invisible to any automated extraction.

  4. 4

    Map the components that already exist in code

    Only now is tooling worth introducing, and only for components on both sides. Everything unmapped is a build, and knowing which is which is itself useful.

Identity Forge kits are that artefact in prebuilt form: 28 semantic colour roles across light and dark, type and spacing scales, motifs and explicit do's and don'ts, exportable as CSS variables, Tailwind @theme, a shadcn registry item or DTCG/W3C JSON. Browse the kits, or read how to write the brief.

What to expect from the current tools

Calibrated expectations, by task:

Realistic outcome
A throwaway prototype from a mockupGood. Structural debt does not matter in code you will delete
Extracting measurements and valuesGood, and underrated. Dev Mode inspection is the boring, reliable win
A new screen using existing componentsGood with mapping configured. Poor without it
Production markup from a complex framePoor. Visually close, structurally wrong, and the cleanup usually exceeds writing it
Converting a whole design systemNot a conversion problem. Extract the decisions as text instead
Where design-to-code tooling earns its place.

The second row deserves more credit than it gets. Reliable inspection — exact values, real token names, actual component props — removes a genuine daily friction and never claims to do more than it does.

Can AI convert Figma designs to production code?

It can produce code that looks like the frame. Whether that is production code depends on structure, and structure is what a frame does not contain — component identity, semantic roles, responsive behaviour between breakpoints. Expect visually close and structurally wrong, and budget for the cleanup.

What is Figma Code Connect?

A feature that links design components to your real code components, so Dev Mode shows the actual component and its props instead of generated CSS. It changes the problem from generating new markup to referencing code you already maintain, which preserves reuse, tokens and accessibility work.

Why does design-to-code output use hardcoded colours?

Because the fill in the frame is a value, and the converter has no way to know which semantic role that value plays. Matching your Figma variable names to your CSS token names is what gives the tooling something to reference instead of a hex code.

How do I get my Figma design system into code?

Not by converting screens. Export the variables as semantic tokens with roles attached, write the scales down as numbers, write down what the library refuses to do, and only then map the components that exist on both sides. That is a day of work and it makes ongoing conversion unnecessary.

Should designers and developers use the same token names?

Yes, and it is the highest-return change available for the effort. When a designer says font-scale-4 and a developer types font-scale-4, there is no translation step and therefore no place for meaning to leak. Salesforce built SLDS 2's Figma library on exactly this parity.