How to hand a design to a developer so it is accepted the first time
August 28, 2026 · 10 minutes · Tomsa Daria
A developer asks the same eight questions about any design. Let us look at how to answer them in advance — with the structure of the file, tokens, states and text beside the screens.
What the developer is actually asking
A design shows how the interface looks in one particular state with one particular set of data. Everything else the developer will either ask about or invent. Questions cost time; invented answers cost rework. Here is the list that repeats from project to project:
The answers to those eight questions are the specification. It does not have to be a document: a text block beside each screen, listing what happens and what does not, is enough. Further on in this article — how to prepare the file itself, so that the specification does not also have to explain where everything is.
- What happens on a press? A transition, a modal, a change in place. And where the «back» button returns to.
- Where does the data come from and what if there is none? An empty catalogue, a product with no photograph, a missing old price.
- What about long and short data? A 120-character title, a six-digit price, a user name of one letter.
- The form validation rules. When the error is shown — while typing, on losing focus or on submit. And the exact error texts, not the word «error».
- What happens while waiting? The button is disabled, a skeleton is shown, the screen does not jump.
- What is visible when working from the keyboard? The tab order, where the focus ring is, what Escape closes.
- How do the blocks behave as it narrows? Not «make it responsive» but the behaviour of every block.
- What is not in the task. An explicit list: no favourites, no social sign-in. An unclosed boundary of the task is a source of conflict at acceptance.
Order in the file: pages, naming, what to delete before handover
The file a developer opens is not built like the file a designer works in. A designer wants a canvas with drafts and variants; a developer needs one answer to the question «what do I build». Order in the file is a way of giving that answer, not an aesthetic habit.
Bring the page list to this shape: → Ready for dev, 01 Screens — desktop, 02 Screens — mobile, 03 Components, 04 Styles and variables, 05 Archive. The arrow in the first page's name lifts it to the top and says at once where to go. On the «Ready for dev» page you put not copies but the actual current screens: duplicates diverge within a week and become a source of mistakes.
Inside a page, group the screens into Sections (the Shift + S key) by scenario: «Catalogue», «Product», «Cart», «Service states». A section has a Ready for dev toggle — switch it on for the finished sections and they will be marked in dev mode.
What to delete and clean up before handover: layers hidden with the eye — they stay in the file and end up in the export; detached instances — a layer with the component's name but no diamond; duplicate styles of the kind Body / M and Body/M 2, which appear when copying from other files. Bring the names to one system: screens by scenario and state («Catalogue», «Catalogue / Empty», «Catalogue / 375»), components by type («Button / Primary»), layers inside a component by role («Label», «Icon») rather than «Text 4».
Do not delete drafts — move them to the «Archive» page. In a month the client will ask why a variant was rejected, and the variant has to be findable. And create a named version: File → Show version history, a point named something like «Handover to development». That is the only way to return to the state that was agreed.
A dangerous habit worth dropping straight away: several copies of one screen named «Catalogue final», «Catalogue final 2», «Catalogue final done». The developer will take the wrong one, and it will not be their fault. The rule is simple: one task — one screen.
In the «Interfaces in Figma» course a whole final module is given to handover, and the materials include a handover template: the file structure and the checklist that get a design accepted without a hundred follow-up questions.
Tokens and styles instead of «just colours»: why this saves rework
In dev mode, selecting a layer shows sizes, spacing, colours and typography in the panel on the right. The difference between a good design and a bad one is visible exactly there: the name action/primary in the panel is useful, while a bare #2F5D3A makes the developer create yet another nameless constant. A month later the code holds eight shades of green and nobody can say which of them are the same colour.
The minimum worth assembling even in a small project: text styles (headings, body, captions), colour variables with roles, numeric spacing variables. The role matters more than the shade: text/secondary will survive a change of palette, while gray-500 in a dark theme stops being grey and starts lying.
A good name follows the grammar «category — role — state»: bg/surface, text/primary, border/default, action/primary-hover, status/error. There is one check: read the name and try changing the value. If the name stops being true, it was named after appearance rather than role.
The saving here is counted in reworks. The client asks for a darker accent colour — in a file on variables that is one value; in a file with hand-painted layers it is an hour and a half and three missed buttons. The same in code: a colour with a name is changed in one place, a nameless one by searching eight files with the risk of touching something else.
Spacing is worth keeping in variables too, especially if the project has a mobile version: numeric variables such as space/section and space/page with Desktop and Mobile modes switch the density of the whole design in one action, rather than by editing every container.
If there are already more than five screens and the colours and sizes in them diverge, that is a separate topic — a design system: an audit of the existing designs, three levels of tokens and the rules by which it is maintained afterwards. But there is no need to start one for a single landing page — up to a certain scale a tidy set of styles is enough.
States: hover, focus, pressed, error, disabled, loading, empty
A design without states is a photograph of the interface at its luckiest moment: the data arrived, there are no errors, the user has pressed nothing. That is the main reason designs get sent back for rework.
The obligatory set looks like this. Default — at rest. Hover — the cursor is over the element; for the mouse only, there is none on a phone. Pressed — the moment of the press. Focus — the element is selected from the keyboard: a ring 2 thick with contrast no lower than 3:1, without which the form cannot be used without a mouse. Disabled — the action is unavailable, and text with the reason is needed next to it. Loading — for a button, replacing the label with an indicator while keeping the width; for a list, a skeleton instead of a spinner in the middle. Error — the error text next to its cause, not a general banner at the top. Empty — an empty cart, an empty search result, a catalogue with no products under the filter.
Not every element needs all eight. A button — default, hover, pressed, focus, disabled, loading. A field — default, focus, error, disabled. A screen — the normal state, loading, empty, load error. The list seems long right up until you build the states as component variants: then it is six cells in a set, not six separate screens.
It is better to show states not as separate pictures but right in the variant set: then the developer sees one component with a switch rather than six different elements. Inside the set the states can be linked interactively — a While hovering transition from Default to Hover and While pressing to Pressed — and they will work in every instance on the screens. It is also a check on yourself: if a transition has nowhere to go, the state has not been drawn.
Two rules worth checking before handover. First: hover cannot be the only way to learn something important — a delete button that appears only on hover is completely unavailable on a phone. Second: an empty screen must have an explanation and an action, not a lonely «Nothing found». The skeleton, meanwhile, must repeat the structure of the cards, otherwise the screen will jump at the moment of loading.
Responsiveness: breakpoints and what happens to each block between them
Responsiveness is not three separate designs but one design with described behaviour. The developer writes one set of markup with several media queries, and the closer your way of thinking is to that, the fewer questions they will ask.
Breakpoints are set by the content, not by a list of popular devices: a point is needed where four cards in a row stop fitting. A working set for a shop is 1440, 1024, 768 and 375; for each one write down the number of columns, the side padding and the gap: at 1440, say, a 12-column grid, 120 of padding, a gap of 24, four cards in a row; at 768 — 8 columns, 32 of padding, a gap of 16, two cards.
Then comes the most valuable part — the behaviour table. Rows: header, promo block, filters, catalogue grid, product card, footer. Columns: the breakpoints. In the cells, one of four kinds of behaviour: stretches (takes the whole available width, with a minimum width), wraps (a row becomes several rows), flips (a horizontal row becomes a vertical column), hides or is replaced (the menu becomes a button, the side filter becomes a popup panel).
Only the last kind has to be drawn: the replaced blocks. The rest is described in words, and that is more honest — three drawn layouts will not cover the widths in between anyway, while a table will.
Separately, for the mobile version, fix the rules for a finger: a minimum tap area of 44 by 44 pixels (the icon can be 24, but the frame around it must be 44), a distance between adjacent targets of no less than 8, text no smaller than 14. The developer will check those numbers, and you will save yourself a round of rework.
Icons, fonts, images: formats and how to hand them over
Icons — in SVG. Before exporting, flatten the outlines (Cmd/Ctrl + E) and convert strokes to fills, otherwise the icon's size in the markup will drift. Set the export up right in the file: the Export section in the Design panel, format SVG.
Raster images — in PNG or WebP, at two densities. The plus in the Export section adds a second preset: 1x and 2x with the @2x suffix.
File names — in Latin letters, with no spaces: icon-cart.svg, hero-plants@2x.png. Non-Latin characters in names break the build on some servers.
The logo — separately and in two variants: colour and single-colour for a dark background.
Fonts. Name the family, the styles and their numeric weights — not «medium» and «bold» but 400, 500, 700. If the font is paid, say so at once and attach a link to the licence: buying a font sometimes takes longer than all the markup. For system fonts, give the fallbacks.
For photographs, name the proportions and the behaviour separately: what aspect ratio a catalogue card has, what to do with a vertical shot, whether it is cropped from the centre or fitted whole. Otherwise on real data half the catalogue will come out squashed.
And a general rule: do not retype by hand what Figma hands over itself. Sizes, spacing, colours with variable names and typography the developer will take from dev mode. Your job is for those values to be right.
What cannot be left «verbal»: animation, error texts, edge cases
The specification is convenient to keep right on the canvas: a text frame 400 wide to the left of each screen. A separate document in another service lives its own life and contradicts the design within two weeks.
Texts. Every error message, hint and empty-state caption — word for word. «Show an error» is not an error text. The same goes for pluralisation rules and formats: «2 items» and «5 items», the price «124 900 ₽» or «€1,249», a date in short or long form.
Animation and transitions. What exactly changes, over how many milliseconds and with what curve. Longer than 200 ms and the interface feels sticky; shorter than 80 ms and the transition does not read. If the animation is not described, it will either not be made or be made at half a second.
Edge cases. A three-line title, a six-digit price, a product with no photograph, an empty filter, the network dropping in the middle of a form submission. The easiest thing is to show them right in the design, as separate frames beside the main screen — that is stronger than any text.
Non-obvious behaviour — with annotations. Switch on dev mode (Shift + D), take the Annotate tool and label the pinned button, the scrolling filter strip, the search field. An annotation is attached to a layer and travels with it, and specific properties can be pinned to it, whose values will update themselves when the design changes.
And the most expensive handover mistake: giving away a design in which spacing was set by coordinates. In dev mode such a block shows distances measured after the fact — 23, 25, 24 — and the developer will repeat those three numbers in the code. Auto layout hands over padding and gap as explicit values; if the blocks in the file fall apart, that is worth fixing first, and we have covered how — in the article auto layout in Figma falls apart.
A live handover: 20 minutes on a call instead of three days of messages
Even a perfect file benefits from a short meeting. Twenty minutes for four points: walk through the whole scenario, show the service states, name the boundaries of the task («this is not in the task»), and agree where questions should be sent.
A check that replaces any self-assessment: give the file to someone who was not on the project and ask them to retell what happens when a card is pressed and what happens if there are no products. If they answer without asking questions, the file is ready. If they start dragging the cursor around the canvas — you know what to write down.
Keep the questions after handover in comments on the design (the C key): a comment is attached to a point in the file, and a week later it is clear what it is about, unlike a list in a messenger. Record the agreements in writing there too — an unrecorded agreement resurfaces at the next meeting as your mistake.
And a short checklist before you send the link: the current screens are on one page and marked Ready for dev; there are no layers with default names, no hidden layers and no detached instances; colours and typography are shown with variable names; export is set up for every icon; the answers to the eight questions from the first section are written for every screen; there is a table of block behaviour by breakpoint; the error texts are written word for word; a named version has been created.
Interfaces in Figma
9 modules · 18 hours · From scratch