Skip to main content

Handoffs Developers Actually Read

By · · 8 min read

On this page

For the first few years of my career, I thought a handoff was a moment. You finished the designs, you dropped a Figma link in Slack, you wrote "let me know if you have questions," and then you moved on to the next thing. The questions came anyway — usually three weeks later, usually in the form of a pull request that looked almost right and was wrong in fifteen small ways.

It took me an embarrassingly long time to realize the problem wasn't the developers. The problem was that I was handing over pictures and expecting people to reverse-engineer the decisions behind them.

A handoff isn't a moment. It's a translation. And like any translation, the quality depends far more on the translator than on the reader.

What developers actually need#

When I started asking engineers what slowed them down, the answers were remarkably consistent. It was almost never "the design is too hard to build." It was:

  • "I don't know what happens when this list is empty."
  • "I can't tell if this spacing is intentional or a Figma accident."
  • "There are three slightly different versions of this button and I don't know which one is real."
  • "The mockup shows the happy path, but the API returns errors constantly."
  • "I don't know what's in scope for this sprint and what's a future idea."

Notice that none of these are visual problems. They're decision problems. The designer made a choice — or, more often, didn't make one — and the developer is left guessing. Every guess is a small bet, and the odds of all fifteen bets landing are roughly zero.

So the goal of a good handoff isn't to describe what the screen looks like. Figma already does that. The goal is to make every decision explicit, so nobody has to guess.

The structure I use now#

Every feature I hand off now comes with the same four things. It's not a heavy process — for a small feature it's maybe an hour of extra work — but it consistently saves days on the other end.

1. A one-paragraph intent#

Before any screens, I write a short paragraph explaining what this feature is for and what success looks like. Not the business case, not the research summary — just the intent.

Something like: "Drivers need to extend a parking session without restarting the whole flow. Success means they can add time in two taps from the active session screen, even with one hand, even if the session is about to expire."

This sounds trivial. It isn't. When a developer hits an ambiguous case at 6pm on a Thursday, the intent is what lets them make a good call on their own instead of waiting for me to wake up. "Two taps, one hand, about to expire" resolves a surprising number of questions without anyone needing to ask.

2. A state inventory#

For every component that changes, I list its states. Default, loading, empty, error, disabled, success, partial — whatever applies. Each state gets a frame, even if it's a rough one.

This is the single highest-leverage thing I do. Most of the "it looks almost right" bugs I used to see came from states I never designed. The developer filled in the gap with whatever seemed reasonable, and "reasonable" in a hurry is usually a spinner and a generic error toast.

If a state genuinely doesn't need custom design, I say so explicitly: "Loading: use the standard skeleton component, no custom treatment." That's still a decision. It's just a cheap one.

3. Annotated edge cases#

Next to the frames, I annotate the cases that will bite us. What happens when the name is forty characters long? What if the user has zero items, or three thousand? What if the currency has no decimal places? What if the timezone changes mid-session?

I don't try to cover everything — that way lies madness. I cover the cases I'd be embarrassed to see broken in production, and I mark everything else as "use your judgment, flag me if it feels wrong." That last line matters. It tells the developer that their judgment is trusted, which makes them far more likely to flag the genuinely weird stuff.

4. A clear scope line#

Finally, I draw a line through the file: this is what we're building now, and this is what we're exploring for later. Design files accumulate ideas the way kitchen drawers accumulate rubber bands. If the "maybe someday" frames sit right next to the "build this now" frames, someone will build the wrong one.

I literally use a section in Figma labelled Not in this release. It's the least glamorous frame in the file and probably the most useful.

Components, not screens#

The other big shift was moving the conversation from screens to components as early as possible.

When I hand off a screen, the developer has to decompose it into parts on their own. When I hand off a screen that's already built from documented components, most of the work is done before the conversation starts. They can see that this card is the same card used on the dashboard, with a different slot filled. They can see that this button is the secondary variant, not a one-off.

This is where a design system pays for itself — not as a style guide, but as a shared vocabulary. When a developer and I can both say "the compact list item with a trailing action," and mean exactly the same thing, a whole category of misunderstanding just disappears.

It also exposes inconsistency early. If I find myself drawing a fourth slightly-different button, that's a signal to either use an existing variant or have an explicit conversation about adding a new one. Better to have that conversation in Figma than in code review.

Talk before you hand off, not after#

The most effective change wasn't a document at all. It was moving the first developer conversation earlier.

I now try to get an engineer looking at rough flows before I've polished anything. Not for approval — for constraints. They'll tell me that the API can't return that data in one call, or that a certain animation will be janky on low-end Android devices, or that a "simple" filter is actually a database query that takes four seconds.

Every one of those constraints is far cheaper to learn at the wireframe stage than after I've spent two days perfecting a layout that depends on something impossible. And developers who were involved early tend to feel ownership over the result, which shows in the final build.

The walkthrough#

When the designs are ready, I do a live walkthrough — twenty or thirty minutes, screen shared, with whoever will build it. I walk through the intent, the main flow, the state inventory, and the edge cases. Then I stop talking and let them poke at it.

The questions that come up in that half hour are gold. They're the exact questions that would otherwise arrive as half-built features weeks later. I write the answers directly into the Figma file as annotations, so the next person who opens it gets the benefit too.

I record these sessions when the team is distributed across time zones. A short recording plus an annotated file covers almost everything a developer in a different region needs, without forcing anyone onto a call at midnight.

After the handoff#

The handoff doesn't end when the walkthrough does. I try to review builds in staging as early as possible, not at the end of the sprint. Small visual drift is easy to fix on day two and annoying to fix on day ten, when three other features are built on top of it.

When I do review, I separate feedback into three buckets:

  • Blocking — the feature doesn't work or misrepresents something important.
  • Should fix — noticeable issues that affect quality but not function.
  • Polish — things I'd love to fix but that can wait for a cleanup pass.

This makes it obvious what actually needs to happen before launch. A flat list of thirty comments, all with equal weight, is just noise — and it quietly teaches developers that design feedback is nitpicking.

The real goal#

None of this is complicated. It's mostly writing things down that used to live only in my head. But the effect compounds. Developers start trusting the files. They stop building the "maybe someday" frames. They flag edge cases instead of guessing. Reviews get shorter because there's less to fix.

The best compliment I've ever gotten from an engineer wasn't about the visual design at all. It was: "I didn't have to ask you anything." That's what a good handoff feels like from the other side — not a moment, but the absence of confusion.