From design to code: what gets lost in the design handoff?
The design handoff is the step where the design is passed to engineering. What gets lost most are decisions you can’t see on screen: tokens, component states, spacing and type metrics, accessibility notes and edge cases. Write every decision down with a name, and keep the names in Figma exactly the same as in code.
In short: what is a design handoff
In a design handoff, a screen from Figma is passed to engineering before it becomes code. On paper, it’s simple: the file link goes out, engineering takes a look and writes the code.
The problem: a screen is a picture; code is behaviour. In the picture, a button appears in a single state. In code, the same button’s focus, loading and disabled states also have to be written.
Engineering makes every missing decision itself. That decision is usually reasonable, but it isn’t the one design would have made. After a few sprints, the product barely resembles its Figma version.
What gets lost in the handoff
In audits and in my own projects, I always see the loss in the same places. What they have in common is simple: none of it is visible in a screenshot.
1. Tokens
In Figma, a button colour can appear only as #1A1916. That value is a colour decision, but without a name, engineering copies it into the code as is. When the brand colour changes, nobody finds that line.
When a value gets a name, it’s called a design token. In Figma, these names are kept as variables; in code, they become CSS variables. If the same name is on both sides, there’s nothing left to discuss about that colour in the handoff.
The check is easy. Click a fill in Figma: do you see a raw colour code or a name? If you see a raw value, that decision can get lost in the handoff.
2. Component states
States are what design files are most often missing. The button is drawn, but not how it looks with keyboard focus or while loading.
For every interactive component, I check these states: default, hover, pressed, focus, loading, disabled and error. Not every component needs all of them. But which one is dropped should be decided by design, not guessed by engineering.
In Figma, states can be kept as variants of a component. If the variant name is the same as the state name in code, engineering doesn’t have to ask what goes with what.
3. Spacing and typography
Spacing gets lost most quietly in the handoff. Design leaves 24 pixels; engineering writes 20 by eye. On one screen, nobody notices; after twenty screens, the page looks messy.
The fix is to bind spacing to a scale. On this site, spacing comes from a scale that grows through 4, 8, 12, 16 and 24 pixels. Each step has a name. When I see a value outside the scale in a design, I note it as a mistake or as a deliberate exception.
In typography, what often gets lost isn’t the font size but the line height and letter spacing. Put design and code side by side, and the difference shows right away. Keep text styles named too, such as “Body” or “Heading 2”.
4. Accessibility notes
A screenshot doesn’t show a keyboard. The order in which you move through the page with the Tab key isn’t in the picture. Neither is how an icon button is read out by a screen reader.
WCAG 2.2 requires this explicitly. Under criterion 2.4.7 (AA), any keyboard-operable interface must have a mode of operation where the keyboard focus is visible. Criterion 4.1.2 (A) requires that the name and role of every component can be programmatically determined.
That’s why, in the handoff, I note the focus order, the accessible names of icons and where the error message is read out. I describe the levels of the criteria in the WCAG guide.
5. Edge cases
A design file is usually drawn with the prettiest data. The name is short; the list ends after five rows. In the real product, the last name wraps onto two lines, the list comes back empty and the request times out.
For every screen, I ask: what do you see when there’s no data, what happens when the request fails, what breaks when the text is twice as long? For empty screens, the empty state pattern helps; for errors, the error message patterns.
If the answer to these questions isn’t in Figma, engineering gives it while coding. Usually the one that’s quickest to write: a blank white area or “An error occurred”.
How a component gets from Figma to CSS
Below, I have mapped five decisions of a button on this site one by one. The first column is the Figma equivalent, the second the token, the third the line in code.
- Default
- Hover
- Focus
- Disabled
- In FigmaFill: variable
surface/inverseToken--surface-inverseCSSbackground: var(--surface-inverse); - In FigmaCorner radius: 18,
radius/mdToken--r-mdCSSborder-radius: var(--r-md); - In FigmaAuto layout padding: 12 and 24Token
--sp-3--sp-5CSSpadding: var(--sp-3) var(--sp-5); - In FigmaText style: Instrument Sans, bold, 17Token
--fs-3--font-bodyCSSfont: 700 var(--fs-3)/1 var(--font-body); - In FigmaVariant: state = focus, disabledToken
--focus--surface-sunkenCSS:focus-visible { outline: 3px solid var(--focus); }:disabled { background: var(--surface-sunken); }
Five design decisions of a button on this site. Press a property: the matching token and CSS line are highlighted, and that part of the component is outlined. The tokens are the site’s real tokens; the names on the Figma side are examples.
No CSS line contains a raw value; every line refers to a name. When a colour or a spacing value changes, only the token’s value changes. Nobody has to touch the CSS lines.
Maintaining this mapping component by component is called a design system. I describe how to build one step by step in the design system guide.
What Figma Dev Mode does
Dev Mode is Figma’s workspace for engineering. According to Figma’s help center, you open it in a design file with the Dev Mode toggle in the toolbar or the Shift D shortcut. It’s included in the Professional, Education, Organization, Government and Enterprise plans.
The features useful for the handoff are below. I have kept the names as they appear in Figma.
- Ready for dev: Design marks a frame, component, instance or section as finished with “Mark as ready for dev”. Marked items collect in the layers panel under “Ready for development”.
- Changed: If a design marked as ready is changed later, Figma sets this state itself. It can’t be set manually. Once the change is finished, the designer clicks “Done with changes”, and the status goes back to Ready for dev.
- Completed: A second status showing that development work is done. According to the help page, marking a design as completed is only available on some plans.
- Inspect: Shows the selected layer’s layout, colour, typography, styles and variables. In the “Code” section, auto-generated code snippets appear; you choose the language or a codegen plugin from a list.
- Variables: You see a variable’s value and mode and follow the alias chain down to the raw value. Figma also suggests variables that match raw values.
- Measurements and annotations: People who can edit the file add measurements with Shift M and annotations with Shift T. The preset annotation categories are Development, Interaction, Accessibility and Content.
- Compare changes: Compares a changed frame with its earlier versions. For a component instance, there is a comparison with the main component.
- Focus view: Opens only one of the designs marked as ready. The other Dev Mode tools work in this view too.
- Figma for VS Code: An extension for browsing and inspecting the design file in the code editor. You see comments in real time and link code files to components in the design.
- Code Connect: Brings real component code from your codebase into Dev Mode. Available on the Professional, Organization and Enterprise plans.
The natural place for accessibility notes is the Accessibility category. If you write the focus order and accessible names there, engineering finds them where it looks.
Two small details help too. If you want a simple list of properties instead of code, switch from “Code” to “List”. To measure the distance between two layers, hold Option (Mac) or Alt (Windows) and hover over the second layer.
I especially like one detail about annotations. According to Figma, a layer property you add to an annotation stays up to date, even if the design changes later.
What Dev Mode doesn’t show
Dev Mode shows what’s in the file. An error state that wasn’t drawn or a focus order that wasn’t written is missing from Inspect too.
Auto-generated code knows no design decision, only the value. If the layer isn’t bound to a variable, the code snippet contains a raw colour. That’s why Dev Mode works well in a file where tokens and states have been set up properly beforehand.
Checklist before the handoff
Before I set a screen to “Ready for dev”, I go through this list. If I can’t answer yes to a point, the screen isn’t finished yet.
- Every colour, spacing, corner and type value is bound to a variable or a style.
- The states each interactive component needs are drawn, and the ones it doesn’t need are noted.
- Spacing comes from the scale, and exceptions are explained with a note.
- Focus order, the accessible names of icons and the place of the error message are in an Accessibility annotation.
- Empty, loading, error and long text are drawn.
- Mobile and desktop widths are shown separately.
- Component and variant names in Figma are the same as in code.
Forms snag most often, because every field has its own error state. I have collected what to watch for field by field in the form design pattern.
Example: handing off a money transfer screen
Think of the transfer screen in a banking app. In Figma, there is a single screen: the recipient’s name, the account number, the amount and the “Send” button. The screen looks clean and goes to engineering like that.
As soon as coding starts, questions come up. Where does the error appear if the account number is wrong? Is the button disabled when the balance isn’t enough, or does it warn only when pressed? What does the button show while sending?
None of this is on the screen. Engineering gives its own answer to each question. The error may appear at the very top of the page, and the button may show nothing while sending. Then the user may press it a second time.
If the same screen goes through the five points before the handoff, the file contains the following:
- The button’s loading and disabled variants, with names.
- The error state of the account number field and the place for the error text right below the field.
- The message for an insufficient balance and the state of the amount field.
- An Accessibility annotation: how the error message reaches the screen reader and where focus goes after the error.
- How a long recipient name wraps onto two lines.
This list adds a few variants and annotations to the file. In return, most of the decisions engineering would have to make alone disappear.
When the handoff should happen
Doing the handoff once at the end is the riskiest way. Engineering gets twenty screens at once and doesn’t know which one is final.
I recommend marking screens as ready piece by piece. When a flow is finished, set it to “Ready for dev”; the rest stays in design. If a marked screen changes, Figma shows it itself, so nobody has to send word by hand.
Also, link the frame, not the file. “Somewhere in the file” increases the risk that engineering looks at the wrong frame.
My note
In my projects, there is almost no handoff, because the same person designs and codes. When I draw a button in Figma, I know I’ll write its CSS too. I name the token in the design and create it in code with the same name.
The explanation is simple: there is no change of hands. When design and code stay in the same head, nobody asks, “What did you mean here?” The number of lost decisions drops too.
Still, I work as if I were handing off to myself. I write edge cases and accessibility notes in Figma, because your team takes over the project later. At the end of the Design & Ship Sprint, the work sits in your repository with these notes.
If design and engineering are separate in your team, this habit helps most: sit down together before the handoff and go through a screen using only the Tab key. Gaps you can’t see in the screenshot come to light quickly in this round.
Questions
What does design handoff mean?
It’s the step where the design is passed to engineering. Besides the screens, decisions about tokens, states and accessibility have to be handed over too.
Which plans include Figma Dev Mode?
According to Figma’s help center, Dev Mode is included in the Professional, Education, Organization, Government and Enterprise plans. Some features, such as Code Connect, are only available on certain plans.
Can you use the CSS from Dev Mode directly?
As a starting point, it helps. But if the layer isn’t bound to a variable, the code contains a raw value. I don’t copy the snippet; I look at which token the value corresponds to.
Is a handoff needed if the same person designs and codes?
With no change of hands, less gets lost. States, edge cases and accessibility notes should still be written down, because someone else will take over the product later.
Sources (6)
- Figma, Guide to Dev Mode, Figma Help Center. accessed November 4, 2026; Shift D, plans, Ready for dev, Inspect, Code and List, Compare changes, Focus view, Figma for VS Code, Code Connect
- Figma, Guide to inspecting, Figma Help Center. accessed November 4, 2026; Inspect properties, Code section, variables, alias chain, suggested variables, measuring with Option/Alt
- Figma, Dev Mode statuses and notifications, Figma Help Center. accessed November 4, 2026; Ready for dev, Completed, Changed, Done with changes
- Figma, Add measurements and annotate designs, Figma Help Center. accessed November 4, 2026; Shift M, Shift T, annotation categories, properties that stay up to date
- W3C WAI, Understanding Success Criterion 2.4.7: Focus Visible (WCAG 2.2). accessed November 4, 2026; AA
- W3C WAI, Understanding Success Criterion 4.1.2: Name, Role, Value (WCAG 2.2). accessed November 4, 2026; A