Frontend Engineering
How does user intent become interactive, accessible, performant pixels in a browser — and how do frontend architecture, browser internals, state, networking, rendering and delivery all interact? Not a React tutorial and not a CSS reference.
How does user intent become interactive, accessible, performant pixels?
The final objective is small and specific. A learner should be able to look at <button>Save</button> and see semantic HTML, the DOM, the accessibility tree, a browser event, application logic, state, a network request, a UI update, style, layout, paint, composite, pixels — and instinctively ask which of those this particular change actually costs.
The order is the argument. What the person intended decides what state must change; what state changes decides what reaches the DOM; what reaches the DOM decides how much of the rendering pipeline runs again before anyone sees anything. Skip a step and you get an interface that is locally reasonable and, on a mid-range phone, unusable.
This is the browser-executed application domain
Frontend Engineering does not own every layer it touches. It owns the application running on someone else's device, and the interaction they actually feel.
API Design decides the contract and Backend Engineering implements the service behind it. The shape of that contract decides how complicated the UI has to be — which is a thing this domain is allowed to have an opinion about, and not a thing it gets to enforce.
The browser-executed application: what runs on the user's device, what it renders, how it responds, what it ships, and what it does when the network, the server or the device lets it down. Accessibility is here in full — no other domain can supply it.
Networking, Security, Performance, Concurrency, Cloud and Agentic Engineering each own a layer in full. Lessons here teach the browser-side mechanism and hand the rest off by name.
Flagship experiences
The parts of this domain that are not reading.
URL, DNS, connection, TLS, request, HTML, parsing, DOM, CSSOM, style, layout, paint, composite, pixels. Every stage is clickable and every stage can be the one you are waiting on.
A person clicks Save. Follow it through dispatch, the handler, a state change, validation, a request, the server, the response, the cache, reconciliation, a DOM mutation — and find out whether it cost layout, paint, both or neither.
One line of JavaScript becomes a DNS lookup, a connection, bytes, a parse and a render. Along the way: what runs on the main thread, what can be cancelled, and what can come back out of order.
Real-shaped evidence and no label. The two signals a user actually feels are raised by almost every fault, so neither one can tell you the cause — the exercise is finding the evidence that can.
The same application under five rendering strategies, on one comparable timeline: when HTML arrives, when content is visible, when JavaScript lands, and when the thing finally responds to a click.
Pick a change and see which pipeline stages it invalidates. The answer is often "it depends what else is on the page", and that is a real answer rather than a hedge.
A modal, a dropdown, tabs, an accordion, a form. Each one has to satisfy keyboard, focus, semantics, screen reader and error messaging before it counts as built.
A decision tree whose every leaf names why, what it costs the browser, what it costs the network, and what you would do instead.
A global multi-tenant SaaS frontend, then nine injected regressions — a 4 MB bundle, out-of-order responses, a duplicated realtime event, a hydration mismatch, a screen reader that cannot navigate it.
Situations with the cause unlabelled. Each one carries the trap: the fix that looks right, passes the obvious test, and leaves the real problem in place.
What each question is really testing, what a strong answer sounds like, and the red flags that separate a remembered rule from a working model.
Learning modules
Thirty-five modules, from what the browser actually is to keeping a frontend working in production for browsers you do not control.
The browser is a runtime, not a document viewer: networking, parsers, a JavaScript engine, a layout engine, a paint system, a compositor, storage and a security sandbox, split across processes that fail independently.
Structured content with behaviour attached. What a `button` gives you that a clickable `div` silently takes away — keyboard, focus, defaults, assistive technology, tooling.
Bytes to tokens to a tree, streaming as it arrives — and what `script`, `defer`, `async` and `type=module` actually do to that stream.
The browser's live object model of the document: nodes, attributes, listeners, computed style, layout boxes and the accessibility semantics derived from all of it.
Cascade, specificity, inheritance and computed style as a resolution algorithm you can reason about, rather than a fight you win with `!important`.
DOM plus CSSOM to style to layout to paint to composite — and the invalidation rules that decide which of those stages a given change actually costs you.
Geometry: the box model, normal flow, flexbox, grid, positioning, intrinsic sizing, overflow — and the read-write-read pattern that forces the browser to compute it all again.
Paint commands, layers, the compositor thread and the frame budget. Why `transform` and `opacity` are often cheaper to animate, stated as a mechanism rather than a slogan.
Call stack, task, microtask checkpoint, rendering opportunity. The scheduling model that explains why a synchronous loop freezes the page and a promise chain does not yield a frame.
Moving CPU work off the thread that owns the DOM: message passing, structured clone, transferables, and the isolation requirements the sharper primitives carry.
Dispatch, capture, target, bubble. Delegation, default actions, pointer and keyboard input, and why cancelling the wrong thing breaks scrolling or accessibility.
The platform's oldest interactive component: input types, native validation, submission, focus order, labels — and what you inherit for free before any framework state exists.
DOM plus semantics plus ARIA becomes an accessibility tree that assistive technology reads. Keyboard operation, focus management and announcement are engineering requirements, not a later pass.
Adapting to available space and user conditions: fluid layout, media and container queries, responsive images, CSS pixels versus device pixels, and typography that survives translation.
Local, form, URL, server, auth, cached and persistent state are different things with different owners. Most frontend bugs are a state-ownership answer nobody wrote down.
Boundaries drawn by responsibility, state ownership and reuse — plus the contract a component owes: inputs, events, slots, behaviour and accessibility.
React, Vue, Svelte, Solid and Angular as different answers to the same questions: how change is detected, how much work is compile-time, and what reaches the DOM.
The URL is application state — shareable, bookmarkable and restorable. Route matching, nesting, history, scroll restoration and the loading boundaries in between.
Request, loading, success or error, render — and the parts that only show up in production: cancellation, deduplication, retries, pagination and background refresh.
Query keys, freshness, staleness and revalidation; updating the interface before the server has agreed, and reconciling honestly when it does not.
Polling, long polling, SSE and WebSocket compared by what they cost — plus reconnect, ordering, duplicate delivery and the resynchronisation nobody prototypes.
Representing identity, sending credentials safely, surviving session expiry and rendering authorization-aware UI — while the backend stays the only authority.
XSS, CSRF, the same-origin policy, CORS, CSP, clickjacking, third-party scripts and supply chain — the browser-side half of a problem the server cannot solve alone.
Cookies, localStorage, sessionStorage, IndexedDB and Cache Storage: lifetime, synchronicity, capacity and exposure. Four different answers to "where does this live".
A programmable proxy between the page and the network: install, activate, fetch, update — plus offline mutation queues and the conflict resolution they imply.
Loading, interaction responsiveness and visual stability measured on real devices, with the main-thread and memory work behind each one. Measure before optimising, always.
The waterfall from HTML to first content: blocking resources, resource hints, HTTP caching, CDNs and content-hashed assets — the network half of how fast a page feels.
Modules to dependency graph to transforms to chunks. Code splitting, tree shaking, TypeScript, polyfills versus transpilation, source maps, and what your users download.
CSR, SSR, SSG, streaming SSR, islands and server components as points on a curve between where work happens and when the page becomes interactive.
Choosing the level by what it can actually prove: pure logic, component behaviour, critical user flow, visual appearance, and the accessibility checks a tool cannot finish.
Errors, failed requests, vitals and interaction latency from real users on real devices — and the privacy obligations that come attached to every one of them.
Reproduce, then work the layers: network, console, DOM and CSS, application state, performance, memory. A method, not a tour of a devtools panel.
MPA, SPA, SSR app, static site and micro frontends; design systems, internationalization, BFFs, deployment — and the fact that web clients never update atomically.
Shipping to browsers you do not control: deployment, feature flags, analytics, uploads, the API contract you consume — and the fact that a web client never updates atomically.
Streaming tokens, tool progress, citations, cancellation and partial failure — plus the rule that a model suggesting an action is never the same as the action being authorized.
Reference
For when you already know roughly what you are looking for.
Nine levels, each unlocking something you can actually build.
The searchable index: what a problem sounds like, and what to think when you hear it.
Twelve pairs people genuinely confuse — minification and compression, polyfills and transpilation, server state and client state — with the confusion named.
React, Vue, Svelte, Solid and Angular across the questions that actually differ — and a column for where the comparison misleads.
Don't delegate understanding
The point of the domain, stated plainly.
Use those abstractions. All of them are worth using, and rebuilding them by hand is not the lesson. But understand how user intent becomes pixels, so that when one of them leaks — and each of them leaks in a characteristic way — you are debugging a system you have a model of rather than one you have been trusting.