Frontend Engineering Roadmap
Start at Structure, style and the object model. Nine stages in one suggested order; every stage names what it needs first and what you should be able to build before moving on, and the stages that look boring are the ones that decide whether the interesting ones work. Progress is stored locally in your browser.
Where to start
Frontend engineering
9 stages · 0/176 lessonsHow user intent becomes interactive, accessible, performant pixels — and what the browser does between a line of code and a visible frame.
- Structure, style and the object model
- Events, forms, accessibility and adapting to the viewport
- State, components, routing and talking to a server
- The rendering pipeline, the event loop and the one main thread
- Client caches, optimistic updates and live data
- What the browser enforces, what you can prove, and what real users emit
- Performance, the critical path and what your users download
- Where the HTML comes from: CSR, SSR, SSG, streaming and islands
- Frontend architecture and running it in browsers you do not control
- 10/20
Structure, style and the object model
Start hereThe browser as a runtime with named parts, then the three things every later stage manipulates: the document (semantic HTML and what a real
buttongives you), the DOM it becomes, and the CSSOM that decides how it looks. What Happens When You Open a Website is the map of the whole stage; the cascade, specificity and the box model come last so you can read a computed value before you try to change one.Before moving on: Build a page whose markup means something, predict which declaration wins for an element, and explain in devtools why it ended up with the computed value it has.
- The Browser Is a Runtime
- What Happens When You Open a Website
- The Multi-Process Browser
- The Frontend Reasoning Loop
- Origins and the Sandbox
- Semantics Are Behaviour
- Document Structure and Reading Order
- What Native Elements Already Do
- The Head: Metadata That Changes Rendering
- Div Soup: How It Happens and What It Costs
- The DOM Is Not Your HTML
- What a Mutation Costs
- Queries, Live Collections and Stale References
- Node Identity Across Updates
- The CSSOM
- The Cascade
- Specificity
- Inheritance and Computed Style
- Custom Properties
- The Box Model
- 20/20
Events, forms, accessibility and adapting to the viewport
How input reaches your code and what the platform already does with it: dispatch, capture and bubble, default actions, pointer and keyboard events. Forms come next because they are the oldest interactive component and most of their behaviour is free. Then the accessibility tree that the DOM and semantics produce, and layout that responds to the space it is given. This sits before state because a component you cannot operate with a keyboard has no state worth managing.
Before moving on: Build a form that submits, validates and announces its errors, operate the whole page with Tab and a screen reader, and lay it out for a phone held one-handed.
Needs first:Structure, style and the object model- How an Event Is Dispatched
- Event Delegation
- preventDefault vs stopPropagation
- Pointer Events
- Keyboard Events
- Native Forms First
- Input Types, Inputmode and Autocomplete
- Native Validation and Its Limits
- Submission: Method, Encoding and Doing It Once
- Errors People Can Actually Perceive
- The Accessibility Tree
- Semantics Before ARIA
- Keyboard Operability
- Focus Management
- The Rules of ARIA
- Live Regions and Announcement
- Fluid Layout First
- Media Queries Beyond Width
- Container Queries
- Responsive Images
- 30/20
State, components, routing and talking to a server
The first real application. Local, form, URL and server state are different things with different owners, so Who Owns This State? comes before any component boundary is drawn. Then components as contracts, how reactivity models detect change and what keys mean to reconciliation, the URL as state you can share, and one
fetchfrom the handler that starts it to the loading and error states it must render. Everything from here on assumes you can say where a value lives.Before moving on: Build a multi-screen app with shareable URLs, components other people can use, honest loading and error states, and an answer to "who owns this value" for every piece of state in it.
Needs first:Structure, style and the object modelEvents, forms, accessibility and adapting to the viewport- The Seven Kinds of State
- Who Owns This State?
- The URL Is Application State
- Derived State
- Form State Is a Draft
- Controlled vs Uncontrolled Inputs
- Drawing Component Boundaries
- What a Component Owes Its Caller
- Composition and Slots
- Prop Drilling, Context and Global State
- Over-Componentization
- Reactivity Models
- Reconciliation and Keys
- Client-Side Routing
- Route Matching
- URL Parameters
- History and Navigation
- The Life of a Fetch
- Loading, Error, Empty — The States You Did Not Render
- Server State Is Not Your State
- 40/20
The rendering pipeline, the event loop and the one main thread
What the browser does between a DOM change and a frame: style, layout, paint, composite, and the invalidation rules that decide which of those a change actually costs (The Cost of a Change is the signature lesson). Then the event loop that schedules all of it on one thread: tasks, microtasks, the rendering opportunity, long tasks, and workers for the work that does not belong there. It comes after the application stage so you have something real to make janky.
Before moving on: Say which pipeline stages a change invalidates before you make it, and when a page freezes, find the task that owns the main thread instead of guessing.
Needs first:Structure, style and the object modelEvents, forms, accessibility and adapting to the viewport- The Rendering Pipeline
- Style Calculation
- Style Invalidation
- The Cost of a Change
- Layout Thrashing
- Paint Commands
- Compositing Layers
- Cheap and Expensive Animation
- The Frame Budget
- Scroll and Input Latency
- The Event Loop, Precisely
- Tasks: The Unit That Cannot Be Interrupted
- The Microtask Checkpoint
- The Rendering Opportunity
- Long Tasks
- What the Main Thread Owns
- Yielding and Scheduling
- Web Workers and the DOM Boundary
- When a Worker Is Actually the Answer
- Streaming HTML
- 50/18
Client caches, optimistic updates and live data
Server state, now taken seriously: a client cache with keys you can invalidate, stale-while-revalidate, and updating the interface before the server has agreed. The middle of the stage is the part nobody prototypes — responses arriving out of order, cancellation, deduplication and retries. Then live transports (SSE, WebSocket), reconnect, duplicate delivery and resynchronisation, and finally which browser storage a piece of state should live in. It builds directly on the fetch lifecycle from the previous application stage.
Before moving on: Build an interface that feels instant without lying: a cache you invalidate deliberately, optimistic mutations that roll back honestly, a live connection that survives a dropped network, and a correct answer for two responses arriving out of order.
- The Client Cache Model
- Query Keys and Invalidation
- Stale-While-Revalidate
- Optimistic UI
- Rollback and Reconciliation
- Out-of-Order Responses
- Cancelling a Request Nobody Is Waiting For
- Five Components, One Request
- Retries, and the Duplicate Order
- Choosing a Real-Time Transport
- Server-Sent Events
- WebSockets in the UI
- Reconnect and Backoff
- Ordering and Duplicate Delivery
- Resynchronisation After a Gap
- State Synchronization
- Persistent Client State
- Choosing Browser Storage
- 60/20
What the browser enforces, what you can prove, and what real users emit
Three kinds of evidence about an application you have now built. Security: the same-origin policy, XSS, CSRF, CORS and CSP as the browser-side half of a defence the server must finish, and where a credential can safely live. Testing: choosing the level (pure logic, component, end-to-end, accessibility) by what it can actually prove. Observability: errors, real-user monitoring and field vitals from devices that are not yours. It sits here because every one of these needs a real app to test, attack and measure.
Before moving on: State which half of a defence the browser does and which half only the server can, write a test at the level that proves the thing you are worried about, and read production signal from real devices instead of your laptop.
- The Browser Security Model
- The Same-Origin Policy
- Cross-Site Scripting
- Sanitization and Trusted HTML
- Cross-Site Request Forgery
- CORS
- Content Security Policy
- Clickjacking and Framing
- Third-Party Scripts and the Supply Chain
- What the Frontend Is Responsible For in Auth
- Cookies vs Script-Readable Tokens
- Storage Security and Durability
- Choosing the Test Level
- Testing Pure Logic
- Component Testing
- End-to-End Testing
- Accessibility Testing
- Frontend Error Tracking
- Real User Monitoring
- Vitals in the Field
- 70/20
Performance, the critical path and what your users download
Measure first, then fix the one thing the evidence points at. Loading, interaction responsiveness and visual stability as concerns with mechanisms behind them; the JavaScript, image, font and memory costs on the main thread; then the network half: the critical rendering path, the waterfall, blocking resources, resource hints, HTTP caching and content-hashed assets, and the module graph your bundler splits and shakes. It needs the pipeline stage to explain what is slow and the field vitals from the previous stage to know where.
Before moving on: Take a slow page, find the actual bottleneck from evidence rather than folklore, fix the one thing that matters, and say what the fix cost.
Needs first:The rendering pipeline, the event loop and the one main threadWhat the browser enforces, what you can prove, and what real users emit- Measure Before Optimising
- Loading: Why Content Arrives Late
- Interaction Responsiveness
- Visual Stability
- The Real Cost of JavaScript
- Images and Fonts
- List Virtualization
- Memoization
- Memory Leaks
- The Critical Rendering Path
- Reading a Network Waterfall
- Render-Blocking Resources
- Resource Hints
- Browser HTTP Caching
- Content-Hashed Assets
- The Module Graph
- Code Splitting
- Lazy Loading
- Tree Shaking
- Minification Is Not Compression
- 80/18
Where the HTML comes from: CSR, SSR, SSG, streaming and islands
Every strategy is a point on one curve between where the work happens and when the page answers a click. CSR, SSR, SSG, hydration and its mismatches, islands, streaming and server components, then the delivery details each one leans on: script loading, the preload scanner, CDNs, module formats, polyfills, TypeScript and bundle analysis. It comes after performance because the choice is a performance trade-off, and after routing because loading boundaries are where the strategies meet.
Before moving on: Choose a rendering strategy from the shape of the content and the traffic, explain hydration to someone whose server-rendered page just ignored three clicks, and mix strategies within one application on purpose.
Needs first:State, components, routing and talking to a serverPerformance, the critical path and what your users download- Client-Side Rendering
- Server-Side Rendering
- Static Site Generation
- Hydration
- Hydration Mismatch
- Islands and Partial Hydration
- Streaming Server Rendering
- Server Components
- Choosing a Rendering Strategy
- Route Loading Boundaries
- `defer`, `async` and `type="module"`
- The Preload Scanner
- CDN Delivery
- ESM vs CommonJS
- Polyfills vs Transpilation
- TypeScript in the Build
- Bundle Analysis
- Source Maps
- 90/20
Frontend architecture and running it in browsers you do not control
The decisions that outlive any one feature: MPA versus SPA versus micro frontends, design systems and tokens, internationalization and locale formatting, and the API contract you consume. Then production: deployment, Long-Lived Clients and Version Skew that never update atomically, feature flags, analytics, uploads, release health, session replay and its privacy cost, a debugging method, and service workers with an offline mutation queue. Last because every choice here is a trade-off between things the earlier stages taught.
Before moving on: Shape a frontend a team can work in for years, ship it behind a flag to clients that update whenever they please, and debug a production incident from field evidence.
Needs first:Client caches, optimistic updates and live dataWhere the HTML comes from: CSR, SSR, SSG, streaming and islands- Choosing a Frontend Architecture
- MPA vs SPA
- Micro Frontends
- Design Systems
- Design Tokens
- Internationalization
- Timezones and Locale Formatting
- Deploying a Frontend
- Long-Lived Clients and Version Skew
- Feature Flags in the Client
- Analytics Events That Answer a Question
- File Upload UX
- How API Shape Drives UI Complexity
- Backend for Frontend
- Release Health
- Session Replay and the Privacy It Costs
- A Method for Frontend Bugs
- The Service Worker Lifecycle
- The Offline Mutation Queue
- What the Frontend Owns in an Agent Product