The handoff between design and engineering is where good products quietly go wrong. A screen that looked effortless in Figma arrives in the browser with the wrong spacing, a hover state nobody specced, and a button that does something the designer never intended. Then comes the sentence every team has heard: "that's not what the design says." In early 2025, the pressure on this seam got sharper. "Vibe coding"—the practice of describing an interface in natural language and letting an AI assistant generate it—entered the industry vocabulary in February, and a wave of design-to-code tools promised to delete the handoff entirely. They have not, and they will not soon: someone still has to decide what correct looks like, and that decision lives in the gap between design and development. As the UI/UX designer at Softechinfra, I run handoff on our web development projects, and over dozens of releases we have replaced the chaotic toss-over-the-wall with a process that holds up regardless of which tools are in fashion. This is that process: the tokens, the specs, the naming, and the review rituals that stop the rework cycle before it starts.
Why Handoff Breaks
Handoff rarely fails because a designer was careless or an engineer was sloppy. It fails because two disciplines describe the same interface in two different languages and assume the other is reading a shared dictionary.
A designer thinks in pixels, intent, and the happy path on a 1440-wide artboard. An engineer thinks in components, states, breakpoints, and every path including the empty list, the 200-character name, and the slow network. When the only artifact passed between them is a static frame, the engineer has to guess at everything the frame does not show—and guesses, compounded across a screen, become the gap between the mockup and the build.
The expensive failures are predictable:
- Undefined states. The design shows the filled form; nobody specced empty, loading, error, or success.
- Magic numbers. A 13px margin that exists nowhere in the system, copied by eye and never reproducible.
- Silent responsive behavior. One desktop frame, zero guidance on what reflows at 768 or 375.
- Naming drift. The designer's "Card / Featured" is the engineer's "PromoTile", and now nobody can find anything.
- Interaction guesswork. Transitions, focus order, and keyboard behavior left to improvisation.
None of these are tooling problems, which is why no tool fixes them outright. They are communication problems with a structural cause, and the fix is structure.
Start With Tokens, Not Screens
The single highest-leverage change a team can make is to stop handing off pixel values and start handing off tokens. A design token is a named decision—color.primary.600, space.4, radius.md, font.size.body—that both the design file and the codebase reference by the same name. The designer picks values once; the engineer consumes names, not numbers.
Tokens collapse an entire category of handoff bugs. There is no "is this 14 or 16px?" because the spec says space.3 and space.3 resolves to one value in exactly one place. When the brand changes a shade, it changes in the token, and every screen that referenced it updates without a single hand-edit. This is the foundation of any real design system, and we go deeper on building one in our design systems implementation guide.
The same logic applies to the type scale, the spacing scale, and elevation. Keep each scale small and deliberate. A spacing scale of seven steps that everyone uses beats a continuous range nobody can predict. Constraint is the feature, not the limitation.
Spec the States, Not Just the Screen
A screen is not a deliverable; a component in all its states is. Before any frame is marked ready for development, it should answer for every interactive element: what does this look like and do in each state it can occupy?
| Element | States to spec | Commonly forgotten |
|---|---|---|
| Button | Default, hover, focus, active, disabled, loading | Focus ring, loading spinner |
| Input | Empty, focused, filled, error, disabled | Error message placement, helper text |
| List / table | Populated, empty, loading, error | Empty state, partial-load skeleton |
| Page | Desktop, tablet, mobile | Reflow rules between breakpoints |
The empty and error states are where products feel either thoughtful or broken, and they are exactly what gets skipped under deadline. A list with no items is not a bug to be discovered in QA; it is a designed moment—a message, an illustration, a call to action—that belongs in the handoff. The same discipline carries into validating the build later; we cover that side in our frontend testing strategies guide, because an unspecced state is an untestable one.
Name Components So Both Sides Can Find Them
Naming is the cheapest coordination tool a team has and the one most often left to chance. The goal is a single shared name for each component that survives the trip from Figma layer to code file.
Three rules carry most of the weight. First, name by what a thing is, not what it looks like—PrimaryButton, not BlueButton, because the blue will change and the name should not. Second, mirror the structure on both sides: if the design library groups components, the component directory should group them the same way, so a search in one place predicts the other. Third, name the props, not just the component: a designer's variant panel (size, tone, state) should map one-to-one onto the engineer's component props. When the variant and the prop share a name, the handoff is half-written before anyone speaks.
This is also why prototyping early pays off so visibly at handoff. When the interaction has already been pinned down in a clickable prototype, the engineer inherits decisions instead of inventing them—a point we make in detail in our guide to prototyping in Figma before you build.
The Handoff Ritual: A Repeatable Sequence
Process beats heroics. The handoff that works is not a document emailed at 5pm; it is a short, repeatable sequence with a live conversation in the middle. Here is the one we run on every feature.
1. Designer self-review against the readiness checklist
Before anyone else looks: all states specced, tokens applied (no detached values), components named, responsive rules noted, copy real not lorem.
2. Walkthrough, not a wall-toss
A 20–30 minute live session where the designer walks the engineer through intent, edge cases, and the why behind the layout. Questions surface here, when they are cheap.
3. Engineer plays it back
The engineer restates the breakpoints, states, and components in their own words. Mismatches between two mental models surface in minutes instead of in a pull request.
4. Build against the spec, flag deviations early
If reality forces a change—a state the design missed, a layout that fights the data—the engineer raises it immediately rather than guessing. Deviations are decisions, made together.
5. Design QA on the real build
The designer reviews the implementation in the browser, on real devices, against the spec. Findings are logged like any other defect, with a tier, not as a vague "it feels off."
The playback step in particular earns its keep. It costs ten minutes and routinely catches the one assumption that would have cost a day of rework. On AppliedView, the analytics platform we designed and built, the data-dense dashboards have far more states than a static frame can show—loading, empty, partial, error, and several density modes. Running this sequence per feature is what keeps those screens matching the design instead of drifting release by release.
A Design QA That Means Something
Design QA fails when it produces a list of subjective complaints. It works when it checks the build against a spec both sides agreed to. Tier the findings the same way engineering tiers bugs:
| Severity | Example | Action |
|---|---|---|
| Blocker | Missing error state, broken responsive layout | Fix before merge |
| Major | Wrong spacing token, incorrect interaction | Fix this release |
| Minor | Off-by-one shade, transition timing | Backlog, batch later |
The tiering keeps design QA from becoming an endless polish loop and keeps engineering from dismissing real defects as nitpicks. A blocker is a blocker whether it came from a tester or a designer.
The Durable Handoff Checklist
Tools will keep changing. The AI design-to-code wave cresting as I write this will reshape who does which step, but it does not change which steps exist. Print this, adapt it, and run it every feature:
- All interactive states specced—including empty, loading, and error
- Tokens applied throughout; zero detached or magic values
- Components named by purpose; variants map to code props
- Responsive behavior documented for every breakpoint
- Real copy, real data ranges—no lorem, no perfect-length strings
- Accessibility noted: focus order, contrast, keyboard paths
- A live walkthrough held; engineer played the spec back
- Design QA run on the real build, findings tiered like bugs
Our CTO Hrishikesh Baidya treats a failed handoff the way he treats a failed deploy: not as someone's fault, but as a gap in the process to be closed. After each project we ask one question in the retro—where did the build diverge from the design, and which checklist line would have caught it? When the answer is "no line would have," we add one. The checklist grows from real misses, not from theory, and that is what keeps it honest.
The promise here is not a perfect first build. It is that the gap between design and code is small, visible, and shrinking—and that "that's not what the design says" stops being a recurring argument and becomes a rare, quickly-closed exception.
Want Handoffs That Don't Cost You a Sprint?
We help product teams build the design systems, specs, and review rituals that turn design-to-dev handoff from a rework cycle into a calm, repeatable step.
Talk to Our Design Team →