Deutsch

Wireframing and Prototyping That Survives Engineering

The first time it happened to me, I almost quit.

I'd spent three weeks on a settings flow. Beautiful Figma file. Every screen. A hover state on the avatar upload because I cared. Eng built it. The empty state was a sad gray box with the word "Empty" in 12px Arial. The error toast was the browser's default red bar. Loading was a generic spinner that appeared instantly, even on local dev where the request took 40ms. The validation message? A native HTML <input> tooltip that said "please match the requested format."

I pinged the engineer. He said, calmly, "you didn't spec it." I was furious. I went back to the Figma. He was right. I hadn't.

That conversation is the entire reason this guide exists. Engineering is not the enemy. Spec gaps are. And spec gaps are a UX problem, not an eng problem.

Why this matters now

Run the math on a single re-do. One feature. One sprint. The empty state is wrong, the error handling is missing, eng has to refactor the component because the variants weren't there to begin with. From my last four jobs, the average cost of one of these re-dos is somewhere around 40 designer hours and 60 eng hours. That's 100 person-hours, blended cost roughly $12,000–$15,000 depending on your team. One re-do per quarter and you've burned $50K a year on rework that a better handoff doc would have prevented.

That's just the dollars. The trust cost is worse. After the second re-do, eng stops trusting your specs and starts building what they think you meant. After the third, your PM stops believing your timelines because "design always needs another round." The handoff isn't a hand-off. It's a contract. Treat it like one and most of this evaporates.

Low-fi vs high-fi: when each one earns its keep

The single biggest mistake I see junior designers make is jumping to high-fi too early. Pixel-perfect mocks before the flow is locked. Eng sees them, gets excited, starts building. Then research comes back and the flow changes. Now eng has shipped half the wrong thing in production code and someone has to explain to the PM why the sprint slipped.

Low-fi is for flow logic and stakeholder buy-in. Paper sketches, Balsamiq, rough Figma frames with placeholder rectangles. The question being answered is "is this even the right idea." Don't pixel-polish a screen you might throw away tomorrow. The deliverable is a clickable prototype that proves the path from A to B makes sense, plus a flow diagram. That's it.

High-fi is for the build. Pixel-perfect, real copy (no lorem ipsum, ever, because eng will copy-paste it and you'll find "Lorem ipsum dolor" on the live login page, ask me how I know), real data shapes, all the states. Only after the flow is locked. If you find yourself fixing layout details on a screen whose flow is still being debated, stop. Drop back to low-fi. Lock the flow first.

The honest test: if a stakeholder is still asking "wait, why does the user go here?" you're not ready for high-fi. Doesn't matter how pretty the rectangles are.

The spec gaps eng will ask about (and you didn't design)

This is the part nobody teaches in design school. Every screen has roughly eight states. You probably designed two of them. Here's the list eng is going to throw back at you the moment they sit down to build:

The eight states every screen needs

  1. Default / populated. The happy path. You designed this one.
  2. Empty. Zero items, zero results, first-time user. What does the user see when there's nothing to see? "No items yet" is not a design. Show me the illustration, the CTA copy, the secondary action.
  3. Loading. Skeleton, spinner, optimistic UI. And the timing rule: how long before the spinner appears? (200ms is the standard threshold; show nothing under that.)
  4. Error. API failure, validation, permission denied, network offline. Each one is different. The 500 error doesn't look like the 403, which doesn't look like "your password is too short."
  5. Partial / degraded. Half the data loaded, some images broken, third-party widget down. Real systems hit this constantly.
  6. Permission variant. Admin, member, viewer, guest. What's hidden vs disabled vs shown-with-tooltip?
  7. Edge data. Long names that wrap, 0 / null / negative numbers, 47 items in a list designed for 5, a tax ID with 32 characters.
  8. Mobile / breakpoints. If the design is desktop-first, what happens at 768px and 375px? "Responsive" is not a spec.

I keep this list pinned next to my monitor. Before any handoff, I walk every screen against the eight states. If a state is "same as default," I write that down. If it's "out of scope for this sprint," I write that down too. The point isn't to design all eight always. The point is to decide all eight, on purpose, and put the decision in the file.

The eight-states gap is the single most common failure I see. Fix this one thing and you've eliminated maybe 60% of the "you didn't spec it" moments.

Figma Auto-Layout discipline

Auto-Layout is not optional. If your file isn't built on it, eng can't see what's a component and what's a frame, can't tell padding from margin, can't predict what happens when copy gets longer. They guess. They guess wrong. Then it's your fault.

Four rules that have saved me hours:

  1. Components, not detached frames. Every reusable element is a component with a name eng can read. A button is Button/Primary/Default, not Rectangle 47. If eng can't see the component name in the inspector, they're guessing.
  2. Real spacing tokens, not eyeballed margins. 4, 8, 12, 16, 24, 32. That's it. If you find yourself typing padding: 13px you're doing it wrong. Pick one and move on.
  3. Constraints set so resizing actually works. Test every component at the largest and smallest size it can be. If a card breaks when the title has 80 characters, eng will hit that bug in production.
  4. Variants for state. Default, hover, active, disabled, loading, error. All in one component, switchable via a property. Eng wires the variant to the state machine and the file becomes self-documenting.

A useful smell test: open your file, click any element, and look at the right-hand panel. If you can't tell at a glance what component it is, what variant it's in, and what spacing token it uses, eng can't either. Fix it before the handoff.

Design tokens: the contract with eng

Tokens are the single most leveraged thing a UX designer can ship. Colors, type scale, spacing, radii, shadows, motion durations: all named, all defined once, all referenced by name in every component.

The contract is simple. When a token changes (say, the brand updates from #0066FF to #0052CC), eng changes one variable, not 40 components. Same goes for type scale, radius, every shadow.

The plumbing has gotten genuinely good. Figma Variables for the source of truth. Tokens Studio (or the native Variables export) to push to JSON. JSON gets imported into Tailwind config, CSS variables, or a Style Dictionary build. Eng never hand-types a hex value. You never re-pick a color from memory.

If you're not on tokens yet, this is the highest-ROI investment you can make this quarter. The first migration takes a week. Every handoff after that gets cheaper.

The handoff doc: Loom plus annotations

The handoff doc is a contract. Verbal handoffs are not. "I'll just talk to eng" is the most expensive shortcut in design. Hallway conversations are great for clarifying. They're terrible for specifying, because in three weeks when QA finds a gap, nobody remembers what you said.

Here's what a handoff doc looks like, in three parts.

Part 1: A 5-minute Loom walking the flow. Open Figma, share screen, hit record. Walk through the flow at the pace of a developer who's never seen it. Call out: the entry point, every screen, the non-obvious behavior ("notice the toast slides in, not fades, 200ms ease-out"), and every state-switch logic ("this empties when the user has zero invoices, but if they had invoices and deleted them all, we show the 'all deleted' variant, not the first-time empty"). I keep this to a 3-minute structure: 30 seconds context, 2 minutes flow walkthrough, 30 seconds gotchas, 30 seconds questions-to-eng.

Part 2: Annotated Figma frames. Numbered callouts on each screen. Not red sticky notes. Real numbered annotations that read like a contract. "1: Avatar. Clicking opens uploader modal. Modal closes on Esc, on overlay click, and on successful upload." Every interaction. Every animation timing. Every edge case the eight-states walk surfaced.

Part 3: Acceptance criteria in eng's language. This is the part designers skip and shouldn't. Acceptance criteria look like:

When the user clicks "Save" with an invalid email, then within 200ms an inline error appears below the field with the text "Please enter a valid email address," the field gets a red border (token: border-error), and focus stays on the field.

That's three behavioral facts (timing, copy, focus state) that QA can verify and eng can build from. Write five to ten of these per screen for any non-trivial interaction. Yes, it's slow. It's slow on purpose. The slow part is where the spec gaps die.

One last rule: link to a single source-of-truth Figma frame. Not 12 files. Not "see exploration v3 and v5 but not v4." One frame. One URL. If you have to point at multiple files, eng will pick the wrong one and you'll deserve it.

The "I'll just talk to eng" failure mode

I know designers who pride themselves on tight eng relationships and treat written handoffs as overhead. I get it. I used to be one of them. The relationship is real and it's worth investing in. But the relationship is not a substitute for the document.

Three problems with verbal handoff:

  1. No record. Six weeks later when QA finds the gap, you and eng will both half-remember a conversation differently. Whoever has more political capital wins. That's not how a design org should work.
  2. No shared understanding. Eng leaves the call with their interpretation. You leave with yours. They overlap maybe 70%. The 30% gap is where the bugs live.
  3. No way to verify post-ship. When you sit down to QA the build, there's nothing to check it against. You're QA-ing vibes.

The rule I now live by: if it isn't written down, it didn't happen. The Loom is written down (it's a recording). Annotations are written down. Acceptance criteria are written down. Hallway "hey, can you also do X" conversations get followed up in writing within an hour, or X doesn't get built.

Post-ship review

The handoff isn't done when eng merges. It's done when you've QA'd the live build against the Figma, together, and logged the gaps.

How I run it: 30-minute meeting on a sandbox or staging environment. Designer and eng share screen. Walk every screen and every state. For each one, three possible outcomes:

  • Match. Move on.
  • Gap, fix this sprint. Log it, file the bug, eng commits to a fix. Usually 1-2 of these per feature.
  • Gap, accept and update Figma. Sometimes eng's version is actually better, or the gap is too small to be worth a sprint. Update the Figma to match reality. Don't leave the file lying about what's in production.

The cardinal sin is the silent fix. Don't passive-aggressively update the next release without telling eng. Don't pretend the gap doesn't exist. Log it, decide together, move on. After a few cycles of this, eng starts trusting that QA is collaborative, not adversarial. They'll start flagging their own concerns earlier in the build.

A reasonable target: ≤3 logged gaps per shipped feature, dropping over time as the eight-states discipline gets stronger.

Measuring success

Three signals tell you the handoff discipline is working.

  1. Zero "you didn't spec it" moments per sprint. This is the lagging indicator. If you're getting these, the eight-states walk wasn't done.
  2. Eng quotes Figma frame names in PRs. "Implements Settings/Profile/Avatar-Upload v2." When eng writes commit messages and PR descriptions that reference your frames by name, your file has become the source of truth. That's the goal.
  3. Post-ship review logs ≤3 gaps per feature. And the gaps trend toward small visual polish, not missing states or wrong behavior.

If all three are true, you've solved the handoff problem. Your role shifts from defending the design to extending it. Which is, finally, the work UX is supposed to be doing.

The Figma file isn't art. It's a contract. Write everything down. Walk the eight states. Record the Loom. Annotate the frames. Write acceptance criteria in eng's language. Run the post-ship review. Do this five times in a row and your re-do rate drops near zero, and you stop dreading handoff Friday.

— Camellia

Learn More