Every project we take on has a moment where the design looks finished and nobody is sure it works. The screens are right, the spacing is right, and yet the team keeps asking the same question in different words: what happens when the list is empty, when a name is forty characters long, when the network is slow? A static file can't answer that. A browser can.
So on most product work we now move into code far earlier than we used to. Not to skip design, but to make the important decisions in the material the product will actually be made of.
Start with the decision, not the screen
Before anyone opens a design file, we write down the decision the prototype has to settle. One sentence, usually in the form "after this ships, a person can ___ that they can't do today". If the client and the crew can't agree on that sentence, no amount of polish will rescue the project.
Then we list what we know, what we're guessing, and what would change our mind. That page sits at the top of the project doc, and it's the first thing we read at every Friday demo.
Design in the material
Static mockups are good at showing how something looks and bad at showing how it behaves. Loading states, empty states, long names, slow networks and keyboard focus all live in code. So our designers and engineers sit together in the first week and work like this:
- Sketch the flow on paper until the steps feel obvious
- Build a rough version with real data, even if it's ugly
- Design the details on top of something that already works
- Put it in front of a real person before it's pretty
A prototype isn't the product. It's the cheapest way to have the argument you were going to have anyway.
Real data matters most. A dashboard designed around tidy sample numbers will break the first time it meets a customer with three years of history. We ask clients for an export on day one, strip out anything personal, and design against that.
Keep the prototype honest
Code prototypes have their own trap: they can look so finished that people forget they're meant to be thrown away. We keep them honest with a few rules:
- It lives on a URL with "prototype" in the name
- It uses the client's real content, never lorem ipsum
- It skips anything that doesn't change the decision: auth, settings, admin edge cases
- It gets deleted or rewritten, never quietly promoted to production
That last rule is the one teams break most often. A prototype is written to learn fast; production code is written to last. Mixing the two is how a two-week experiment becomes a two-year maintenance problem.
Hand over the working thing
When a flow is settled, the hand-off is no longer a sixty-page spec. It's the prototype, the decision log and a short list of what changes for production. This is the kind of note we leave at the top of every prototype branch:
# Checkout prototype · week 2Decision: one-page checkout, guest by defaultReal data: 1,200 orders exported 14 SepKept: address autocomplete, inline card errorsDropped: saved carts (nobody used them in tests)For production: payments service, analytics, a11y auditEngineers start from behaviour they've already clicked through, and designers stay on the project to tune the details instead of disappearing after "final_v7".
The short version
Decide first, design in the real material, keep the prototype honest and hand over something that works. It isn't a method so much as a habit, and it's the one that has made the biggest difference to the products we ship.
