Frontend Design
A 9-step walkthrough to Frontend System Design
The same discipline as backend system design, pointed at a machine you don’t own.
Big Idea
A backend design grows outward: each step earns another box on the diagram. A frontend design doesn’t. The stack is the same nine times over: shell, router, components, store, cache, transport, storage. What each stage changes is who owns which part of it, how long the data inside it lives, and what the user is looking at while it’s still arriving.
So these nine stages are nine passes over one picture, not nine additions to it.
Walk It
Nine Stages, One Stack
Step through it. No stage adds a box after stage 3. Each one lights up the layers it governs, and the ones left grey are somebody else’s problem for now.
Only the two endpoints. A user, and something that has data. Everything between them is still a guess.
Who is on the other side of the screen, and on what device?
You can name the one journey the whole design serves, and the device it has to feel fast on.
End of the nine stages
The Two Axes
Where Every Value On Screen Lives
Stage 4 is the one most designs lose, and it only ever asks two things: who owns this and how long does it live. Two questions make a plane, and each quadrant of it comes with its own instruction.
The quadrant decides the mechanism, not your preference for a library
The Deliverable
Eight States, Not One
Stage 5 asks what is on screen before the data is. This grid is the whole answer to it: eight states, answered for every screen you ship, and a screen with one of them designed is a screen that isn’t finished.
A mockup only ever shows the first one — the data arrived, the list had items, nobody lost their connection. The other seven have no picture to copy, which is why they get discovered in production, one support ticket at a time.
and for how long before you say something
the only one anyone designs
transport, or domain: say which
never used it, versus nothing matched
shown, and labelled as old
what still works, stated plainly
sign in, or you may not: two different screens
optimistic, and reversible
The Budget
What “Fast Enough” Actually Means
A budget is a number you agree on before you build, so that “is it fast enough” has an answer instead of an argument. Without one, every performance technique is optional and nothing can ever be called done, because there is nothing to be done against.
Four of stage 7’s numbers come with the line already drawn. These are the published Core Web Vitals thresholds, the same ones search engines and Lighthouse score you on, so the only question left is which side of them you land on.
Good, needs work, poor. The boundaries are published, not chosen by you
How long until the biggest thing on screen, usually the hero image or the headline, has actually painted. The closest single number to "when does this page feel like it is here".
How long a tap or a keypress takes to produce a visible change. This is the one that decides whether the page feels alive or stuck.
How much the page jumps around while it loads, scored rather than timed. Almost always an image, an ad or a font arriving without its space reserved.
How long the server takes to send the first byte of the response. Everything else on this list only starts counting after it.
The other five have no published threshold, so you have to pick a number and write it down. A budget you chose arbitrarily still beats no budget, because only one of the two can be exceeded. These are reasonable places to start arguing from.
What has to arrive and run before the page works. Measure the route someone actually lands on, not the whole app.
The shape matters more than the number. A tab that climbs while you scroll a long list is leaking rows somewhere.
A frame is drawn every 16ms, so one long task on the main thread is visible as a stutter during a scroll or a drag.
The average hides the slow quarter of your users. Budget the 75th percentile and the number stops lying to you.
Failed requests and caught exceptions per session. This one is not a target to hit, it is a line that pages somebody.
Why This Exists
Why Frontend Design Needs Its Own Order
Backend system design has a settled shape: boxes, arrows, and a request moving between them. Run that playbook on a frontend and you draw three boxes and stop, because the interesting parts aren't components, they're ownership and timing.
The frontend's hard problems are the ones a topology diagram can't show: who owns this value, how stale is it allowed to be, and what is on screen while we find out.
Most frontend design failures are not architectural. They are a state that nobody designed: the empty list, the expired token, the second tab, the request that came back after the user navigated away.
And unlike a server, you don't control the machine your code runs on. The budget is set by the worst device in your requirements, which is why stage 1 has to name it.
The Difference
Same Discipline, Different Physics
The seven step backend walkthroughClarify requirements → estimate capacity → high-level design → database design → interface design → scalability → reliability. Seven steps for the server side, where each one hands something concrete to the next and the first two draw nothing at all.Open the page → and these nine stages are the same instinct (work in an order, produce something at each step) applied to two problems that fail differently.
Common Mistakes
Ways These Nine Stages Get Misused
Answering "design Figma" with a box diagram, when the whole question is how two people editing the same thing converge.
Treating server data as client state, then spending the rest of the project syncing two sources of truth that were never meant to agree.
Reaching for a WebSocket when the requirement was "fresh", not "live", and inheriting reconnect, ordering and resync for nothing.
Designing only the success state, then discovering the other seven in production one support ticket at a time.
Optimising renders before measuring, while the actual cost is an unsplit bundle and three fonts.
Listing performance techniques without a budget, which makes every one of them optional and none of them checkable.
Hiding a button for permissions and calling it authorization, when the endpoint behind it never checks.
Walking through all nine stages as topics to mention rather than decisions to make, which produces a vocabulary demonstration instead of a design.
Key Points
What To Carry Out Of This
The stack doesn't change; the ownership does. Stage 3 names the boxes once, and every later stage claims the ones it governs rather than adding new ones.
Frontend design is state design. Lifetime and ownership are the two axes, and almost every disagreement about architecture is really a disagreement about one of them.
"Fresh" and "live" are different requirements. Only one of them costs you a socket, reconnect logic, and event ordering.
The eight UI states are the deliverable, not a checklist. A screen with one state designed is a screen that isn't finished.
A budget makes performance checkable. Without a number, every technique is a suggestion and nothing can be said to be done.
Nothing on the client is a security control. It can be a convenience over one, and that's the most it can ever be.
Every stage has a tell. If you can't say what you walked away with, you named the stage instead of doing it.
Answered In Full
The Same Decisions, As Interview Questions
A stage names the decision; these are the mechanisms underneath it, each written out the way you would say it in the room. They open on the Q&A page and come back here when you close them.
Stage 2 · Place the boundary
Stage 3 · Name the parts
Stage 5 · Design the waiting
Stage 6 · Harden the wire
Stage 7 · Spend the budget