Frontend Engineering Roadmap
Nine levels, each defined by what you can build once you have it rather than by what you have read. The order matters: every level assumes the failure modes of the one before it, and the levels that look boring are the ones that decide whether the interesting ones work.
Structure, style and the object model
You can build a page whose markup means something — headings that outline the document, controls that are real controls, styles that resolve the way you predicted — and you can open devtools and explain why a given element ended up with the computed value it has. This is the level at which the browser stops being a mystery box and becomes a machine with named parts.
Events, forms, accessibility and adapting to the viewport
You can build an interface that a person can actually operate — with a keyboard, with a screen reader, on a phone held one-handed, in a language that runs longer than English. Forms submit, errors are announced, focus goes where the user expects, and the layout responds to the space it is given rather than to the width of your laptop.
State, components, routing and talking to a server
You can build a real application: multiple screens with shareable URLs, components with contracts other people can use, and data that arrives from a server with its loading and error states rendered honestly. Crucially, you can answer "where does this value live and who owns it" for every piece of state in the app, which is the question most frontend bugs turn out to be.
The rendering pipeline, the event loop and the one main thread
You can look at a change you are about to make and say which pipeline stages it invalidates and roughly what that costs — and when a page freezes, you can find the task that owns the thread instead of guessing. This is the level at which "it feels janky" becomes a diagnosis rather than a complaint.
Client caches, optimistic updates and live data
You can build an interface that feels instant without lying: a cache with keys you can invalidate deliberately, mutations that render before the server has agreed and roll back honestly when it disagrees, and a live connection that survives being dropped in a lift. You can also say what happens when two responses to the same screen arrive out of order.
What the browser enforces, what you can prove, and what real users emit
You can state precisely which half of a defence the browser is doing and which half only the server can, write tests at the level that can actually prove the thing you are worried about, and read production signal from real devices instead of from your own machine. You stop shipping "it worked locally" as a release note.
Performance, the critical path and what your users download
You can take a slow page, find the actual bottleneck from evidence rather than folklore, and fix the one thing that matters — whether that is a blocking resource, a long task, a render that did not need to happen or three hundred kilobytes of a date library nobody imports. You can also say what your fix cost, because every one of them costs something.
Where the HTML comes from: CSR, SSR, SSG, streaming and islands
You can choose a rendering strategy from the shape of the content and the shape of the traffic rather than from what the framework's landing page recommends, and you can explain hydration to someone who has just watched their server-rendered page ignore three clicks in a row. You can also mix strategies within one application on purpose.
Frontend architecture and running it in browsers you do not control
You can shape a frontend that a team can work in for years — architecture chosen for the constraints that actually apply, a design system with tokens rather than a folder of components, i18n that was not bolted on, and a deployment story that survives the fact that web clients never update atomically. You can debug a production incident from field evidence and ship the fix behind a flag.