Building the part of a system a person operates directly: the browser as a runtime with its own scheduling and rendering rules, state and component architecture at the point where senior work actually lives, performance measured against real devices, and accessibility as both a craft and a legal obligation.
Very high demand22 min readFrontend engineer, Full-stack engineer (frontend-leaning), UI engineer / design systems engineer, Web performance engineer, Accessibility engineer, Frontend architect / staff frontend engineer, Mobile web engineerUpdated 2026-07-27
Assumes you know: JavaScript beyond syntax, including closures and asynchronous execution, HTML and CSS well enough to build a page without a framework, HTTP basics, including status codes, caching headers and what a request costs
Overview
What this area actually covers
Frontend engineering is building software that runs on a machine you do not own, over a
network you cannot predict, for a person who is holding it. Nearly everyone
underestimates the scope, because the visible output is a screen and the screen looks
simple.
Four things sit underneath. The browser as a runtime: a single-threaded JavaScript
execution model with its own task scheduling, a document tree that is expensive to
mutate, an event system, several incompatible storage options, and a security model
built on origins. Rendering and performance: the pipeline from markup and
stylesheets to pixels, and what it costs to disturb it on a mid-range phone rather than
your laptop. State and component architecture: deciding what data exists, who owns
it, when it is stale, and how a change propagates without the application becoming a
web of implicit dependencies. Accessibility: making the interface operable by
keyboard, by screen reader, and by someone who cannot perceive colour or hold a pointer
steady.
What gets wrongly bundled in is mostly design. Choosing typography, spacing and colour
is design work; implementing it faithfully across viewports is frontend work, and the
two are related but not the same skill. Nor is frontend simply "React", which is one
answer to a subset of the problem. Treating the framework as the discipline is the
commonest reason a candidate who has shipped for three years cannot explain why their
page is slow.
The section is split into nine topics, and the split follows how frontend interviews are
actually structured rather than how a curriculum would organise it. Three topics are
language and type system, three are framework, and three are the platform beneath all of
them. The last group is the part that keeps its value longest.
Topic
What it is for
JavaScript Core
The language semantics every frontend screen opens with
TypeScript
Expressing component and data contracts so the compiler enforces them
React
The dominant framework, and the reasoning its model demands
Angular & Vue
The other two mainstream models, with different reactivity assumptions
Browser & Rendering
The runtime itself, which every framework sits on top of
Web Performance
Measuring what a user experiences and fixing the specific cause
CSS & Layout
Making a layout hold under real content on real viewports
Accessibility
Making the interface operable by everyone, and passing an audit
Frontend System Design
Architecting a client application rather than a component
JavaScript Core is where nearly every frontend interview begins, and it goes deeper
than the syntax. Closures and why a variable captured in a loop behaves as it does,
the event loop and the ordering guarantees between a promise callback and a timer,
prototypes and how property lookup really resolves, coercion and the small set of rules
that explain the notorious comparisons, and the async semantics that make the difference
between code that works and code that works most of the time. It exists first because
every other topic assumes it.
TypeScript is treated separately because its type system is unusual enough to be its
own subject. Structural typing means compatibility is decided by shape rather than by
declared inheritance, which surprises people arriving from nominal languages. Generics,
narrowing through control flow, discriminated unions for modelling states that cannot
coexist, and the utility types that let you derive one contract from another are the
recurring content. In interviews it usually appears as "type this component's props
correctly", which is a design question wearing a syntax costume.
React gets its own topic because it is the framework most jobs use and because its
model has specific, gradeable consequences. Reconciliation and why keys matter, the
rules of hooks and why they exist, dependency arrays and the class of bugs a wrong one
produces, when a re-render is a problem and when it is not, server components and the
boundary they draw between what runs where, and the choice between local state, context
and an external store. The questions have moved over time from lifecycle trivia to
correctness of effects and data flow.
Angular & Vue cover the two other mainstream models, and they are worth
understanding even if you use neither, because they make the reactivity trade-off
explicit. Angular's dependency injection and change detection, and Vue's reactive
primitives, solve the same problems React solves with different defaults, and being able
to compare the approaches is the fastest way to demonstrate that you understand the
problem rather than one solution to it. If the role uses one of them, expect
framework-specific lifecycle and module questions.
Browser & Rendering is the platform topic and the one that ages best. The critical
rendering path from bytes to pixels, the difference between a reflow and a repaint and
which operations trigger which, event capturing and bubbling and why delegation works,
the storage options and their differing lifetimes and size limits, and how cookies
behave across origins. Everything a framework does eventually reduces to operations
described here, which is why senior interviews spend disproportionate time on it.
Web Performance is measurement first and optimisation second. The topic covers Core
Web Vitals — Largest Contentful Paint, Cumulative Layout Shift and Interaction to Next
Paint, which replaced First Input Delay as a Core Web Vital in March 2024 — along with
bundle splitting, image strategy, font loading and the distinction between laboratory
and field data. Its central discipline is refusing to guess: you measure, you find the
specific cause, you fix it, and you measure again, and a candidate who describes that
loop scores above one who lists techniques.
CSS & Layout is underrated by candidates and is a common source of quiet failure in
practical exercises. The cascade and how specificity resolves a conflict, flexbox and
grid and which problem each is for, stacking contexts and why a z-index that ought to
work does not, containing blocks and how position interacts with transforms, and a
responsive strategy that survives text scaled up and content longer than the design
assumed. It is a separate topic because the failure mode is not ignorance but
half-knowledge that holds until something unusual happens.
Accessibility covers semantics first, then interaction, then the standard. Native
elements and the behaviour they bring for free, keyboard operability and focus
management, ARIA and the specific ways it is misused, and the WCAG success criteria that
come up in review and procurement. It is its own topic rather than a footnote on
components because a large part of it is process — how you test, with what, and at what
point in the workflow — rather than knowledge of individual attributes.
Frontend System Design is the client-side counterpart to the backend design round,
and it is increasingly a distinct interview. You are asked to design something like an
autocomplete, an infinite feed, a collaborative editor or a dashboard, and the graded
material is component boundaries, the data-fetching and caching layer, how state is
normalised, what happens offline or on a slow connection, and how the design degrades
rather than breaks. It sits last because it draws on all eight of the topics above.
Where it sits in a real system
The frontend is the boundary where an internal data model becomes something a human can
act on, and that translation is lossier than it looks. Your API returns entities; a user
thinks in tasks. Almost every hard frontend problem lives in that gap.
Mechanically, you sit at the end of a delivery chain. HTML arrives, the browser parses
it, discovers CSS and JavaScript, builds a DOM and a style tree, computes layout,
paints, and composites. Blocking resources stall that pipeline. Then your JavaScript
takes over and the second life of the page begins: fetching, caching, mutating,
re-rendering.
Loading diagram…
The step to watch is C, because a stylesheet blocks the pipeline from reaching D at all
— the browser will not paint content it might have to restyle. That is why a render-
blocking stylesheet in the head delays first paint for every user, and why a synchronous
script placed before it is worse still, since script execution can query layout and so
must wait for style to be ready. Nearly every first-paint problem is one of those two
things.
That gives you three architectural decisions that outrank every library choice. Where
rendering happens — on the server per request, at build time, in the browser, or a
mixture — which determines what a user sees before your code runs. Where state lives
— server as source of truth with a client cache, or a client store you synchronise by
hand. What crosses the network and when, because a beautifully structured client
making eleven sequential requests is slower than an ugly one making two.
Those three decisions interact, which is what makes them architecture rather than
configuration. Choosing server rendering changes where your state can live, because
anything computed on the server has to be serialised and sent for the client to pick it
up. Choosing a client cache as the source of truth changes what crosses the network,
because the cache decides when a request is unnecessary. Getting the three to agree is
most of what a frontend architect does, and a candidate who treats them as independent
choices usually produces a design with a contradiction in it.
The frontend is also where security assumptions are most often misplaced. Anything you
send to the browser is public, and any token you hold there is reachable by injected
script. Client-side validation improves the experience; it never enforces a rule.
Choosing where rendering happens
Because the rendering decision outranks the framework decision, it deserves to be laid
out plainly. The options are not competing fashions; each optimises a different thing
and each has a cost you will feel later.
Strategy
First paint contains
Best for
The cost you pay
Client rendered
An empty shell
Highly interactive apps behind a login
Slow first paint, weak crawlability
Server rendered per request
Full content
Personalised, frequently changing pages
Server cost and latency on every request
Statically generated at build
Full content
Content that changes rarely
Rebuilds to publish, stale until then
Static plus revalidation
Full content
Content that changes on a known cadence
Complexity, and a window of staleness
Streamed with partial hydration
Content progressively
Large pages with a slow section
Harder mental model, tooling dependence
The row people choose by default is the first, and the reason it dominated for years is
organisational rather than technical: a client-rendered application needs no server-side
runtime for the interface, so one team can own everything. The cost lands on users with
slow devices, because a shell that arrives quickly still shows nothing until a large
JavaScript bundle has downloaded, parsed and executed.
The important thing to be able to say in an interview is that the choice is per route,
not per application. A marketing page, a search results page and an authenticated
dashboard in the same product have different requirements, and a mature answer assigns
each of them a strategy and justifies it from what the page is for. Committing the whole
application to one strategy because the framework's default suggested it is the answer
that reads as junior.
Who does this work
Product frontend engineers build features: a day is reading a design, working out which
existing components apply, discovering the API does not return what the screen needs,
negotiating that, then handling the states designs habitually omit — empty, loading,
partial, error, offline, too much data.
Design systems and UI engineers build the components everyone else consumes. The work is
closer to library authorship: API design, accessibility correctness done once so that
fifty consumers inherit it, and versioning changes that will break somebody.
Specialists exist where the stakes justify them. Performance engineers work from field
measurement to specific regressions. Accessibility engineers audit against WCAG success
criteria, test with actual assistive technology, and sit close to legal and procurement.
Frontend architects decide rendering strategy, module boundaries and build tooling for
many teams.
The distinction between building and consuming components is worth keeping in mind when
you read a job advert, because it changes the interview. A product frontend role will
test whether you can turn an ambiguous design into a working screen with all of its
states handled. A design systems role will test API design, backwards compatibility and
accessibility depth, and will care far more about the interface of your component than
about the screen it appears on. Both call themselves frontend engineering, and preparing
for one leaves you noticeably underprepared for the other.
Separately, a large population operates frontends without building them: analytics and
experimentation teams, marketers deploying tags, content editors in a CMS. Their changes
ship to your page and can undo your performance work, which is why tag governance is a
frontend concern.
Demand, adoption and how that is changing
Demand is very high in aggregate, but it is not evenly distributed, and being honest
about that matters more than the headline. Junior frontend is the most crowded entry
point in software: it is the most tutorialised path, the barrier to producing something
that looks finished is low, and screening now leans on browser-platform depth precisely
to separate candidates that a portfolio cannot. Senior frontend is genuinely scarce.
People who can own rendering strategy, untangle state in a large application, and hold
accessibility and performance as engineering requirements are hard to hire, and
companies feel it.
Three forces keep demand structural. Interfaces keep getting richer, so more of the
product's complexity moved into the client and stayed there. Accessibility acquired
legal weight rather than merely ethical weight — the European Accessibility Act's
obligations took effect in June 2025, and public-sector accessibility rules already
applied across the EU and the UK — so conformance is now a procurement gate, not a
nice-to-have. And performance is tied to revenue closely enough that Core Web Vitals are
tracked as a business metric.
The framework question deserves a straight answer. Churn is real but it is shallower
than it feels: the durable knowledge is the platform underneath, and the platform has
been stable and improving for years. Interviews have noticed. A senior frontend loop
today is more likely to probe the event loop, rendering cost, caching, forms and
semantics than the current idiomatic way to write a hook, because interviewers know
framework idiom decays and platform knowledge does not.
There is one more shift worth naming, because it changes what a junior portfolio is
worth. Generating a plausible-looking interface is now cheap, so a screenshot no longer
distinguishes anyone. What distinguishes a candidate is the ability to say why the
generated version is wrong — that the modal traps focus incorrectly, that the list
re-renders on every keystroke, that the image has no dimensions and so shifts the
layout. That is a critique skill, and it is built by measuring and auditing real pages
rather than by building more of your own.
What makes it hard
The genuine difficulty is that you are writing concurrent, stateful software in an
environment you cannot control, and every hard bug lives in the interaction rather than
in one file.
The conceptual leap is derived state. Beginners store what they can see; the
discipline is storing the minimum that cannot be computed, then deriving the rest. Once
the same fact exists in two places they will disagree — the list says the item is
deleted, the detail panel says it is not, and no single component is wrong. Server state
makes this sharper because it is a cache of somebody else's data: it can go stale
between paint and click, and every serious client eventually needs a story for
invalidation, request deduplication and optimistic updates that can be rolled back.
What only bites in production is the environment. Your development machine is fast, near
the server, and has a warm cache. The real user has a mid-range Android device, high
latency, an extension injecting script, a translation layer rewriting the DOM, and text
scaled to 200 per cent. Layouts that survive nothing else survive real content: names
longer than the field, a currency that renders wider, a language that reads right to
left.
Accessibility is where experience is least substitutable, because it is not a checklist
you can reason through cold. You can pass automated checks and still ship something
unusable — tooling catches a real but limited fraction of WCAG failures, and the rest is
focus order, meaningful names, and whether a change gets announced. The reliable
heuristic is that native semantic elements come with behaviour you would otherwise have
to rebuild correctly, while ARIA changes what a browser reports without adding any
behaviour at all.
// Two divs given a role. Nothing about them is actually a button, and// role= does not add keyboard activation, focus, or disabled semantics.
<div role="button" onClick={submit}>Submit</div>
// The element that already is one: focusable, activated by Enter and Space,// announced as a button, participates in the form, honours `disabled`.<buttontype="submit">Submit</button>
The states nobody puts in the design
A design file shows one state: the successful one, with plausible content of a
convenient length. Everything else is your problem, and the gap between a junior and a
senior implementation of the same screen is mostly this list rather than anything
architectural.
The empty state is the first screen a new user sees and is therefore the most
important one in the product, which is precisely why it is usually an afterthought
rendering as a blank panel. The loading state has to decide between a spinner, a
skeleton and showing nothing, and the right answer depends on how long the wait usually
is: a spinner that flashes for eighty milliseconds is worse than no indicator at all,
which is why deliberate delays before showing one are common. The partial state
arises when one of three requests has returned, and the choice is whether to render what
you have or hold everything back until all of it arrives.
The error state is where most implementations are weakest, because a single generic
message covers cases that need different responses. A validation failure is the user's
to fix and belongs next to the field. A transient network failure is worth retrying and
the interface should offer that. An authorisation failure means the user should not have
been offered the action at all, which is a bug one layer up. A server error is nobody's
fault and needs a way out that does not lose what they typed. Collapsing all four into
"Something went wrong" is a decision, and usually the wrong one.
Then there are the states the environment imposes rather than the data. Offline, and
whether your application detects it and queues rather than silently discarding.
Stale, where the data on screen was true when it was fetched and is not now, which
matters enormously on a page someone leaves open all day. Too much data, where the
list the design showed with six rows has four thousand and every approach to rendering
them has a cost. And content that does not fit, which is not really a state but
behaves like one, because a name twice as long as the mock or a translated string half
again as wide breaks layouts that were never tested against them.
Enumerating this list unprompted in a frontend design interview is a strong signal,
because it demonstrates that you have shipped something rather than built something. The
follow-up worth preparing is which of these states you would represent explicitly in your
model — a single discriminated status rather than three independent booleans, so that
loading-and-error cannot both be true and the impossible combinations simply cannot be
constructed.
The single thread, precisely
Half the asynchronous bugs in frontend code, and a large share of the interview
questions, come from an imprecise model of what "single-threaded" means. It does not
mean one thing happens at a time in the browser; the browser does plenty in parallel. It
means your JavaScript runs on one thread, and while it is running, nothing else on that
thread can — including painting.
The loop has a definite shape. The engine takes one task from the task queue and runs it
to completion. When it finishes, it drains the microtask queue entirely, and any
microtask that queues another microtask is also drained in the same pass. Only then may
the browser proceed to a rendering opportunity, where it runs animation-frame callbacks,
recalculates style and layout, and paints. Then it takes the next task.
Loading diagram…
The consequence to hold on to is the shape of the decision box. Rendering is not
guaranteed after every task; it happens when the browser judges a frame is due, and it
cannot happen at all while a task is running. So a single long task — an expensive
computation, a synchronous loop over thousands of rows — blocks paint and blocks input
handling for its whole duration, which is exactly what a poor Interaction to Next Paint
score is measuring. Splitting that work into smaller tasks does not make it faster; it
makes the page responsive while it happens, which is a different and usually more
valuable thing.
The second consequence explains a classic interview question. A promise callback is a
microtask and a timer callback is a task, so a resolved promise's continuation always
runs before a timer scheduled with zero delay, even though the timer was registered
first. That is not a quirk to memorise; it falls straight out of the loop above, and a
candidate who derives it from the model rather than reciting the outcome is
demonstrating the thing being tested.
A last consequence is that heavy work does not belong on this thread at all. A web worker
runs on its own thread with no access to the DOM, which is a limitation and also the
point: parsing a large response, running a search index or doing image work there leaves
the main thread free to paint and to respond to input. Knowing when to reach for one, and
being clear that it solves a responsiveness problem rather than a throughput problem, is
the natural end of this line of questioning.
Why study it
Learn frontend if you want the shortest feedback loop in software — you change a line
and see the consequence — and if the fact that a real person uses your output directly
is motivating rather than incidental. It is also the best available education in
event-driven, asynchronous programming, because the browser gives you no choice but to
reason about it, and that transfers.
The senior case is stronger than the junior one. Frontend architecture, state design and
performance work are scarce skills attached to visible business outcomes, and
accessibility expertise is scarce enough to be a career on its own.
Be honest about who should not bother. If your goal is machine learning, data
engineering or systems programming, this is a detour. If you want the highest-paid
backend role in the least time, distributed systems and databases are a more direct
route. And if what you enjoy is visual craft rather than programming, product design
will suit you better than a frontend loop that spends an hour on the event loop.
If you are entering at the junior end anyway, the honest strategy is to be
uncharacteristic. The crowded portfolio is a handful of applications built from
tutorials; the uncrowded one is a documented performance improvement on a real site, an
accessibility audit with the failures and the fixes, or a component whose keyboard
behaviour you can defend in detail. Depth in the platform is both rarer and cheaper to
acquire than breadth across frameworks, and it is what the screening round is now
designed to find.
Your first hour
Take a page you did not build and measure it, because the habit of measuring rather than
guessing is the whole of performance work.
Open a content-heavy public site in Chrome DevTools, and in the Network panel set
throttling to a slow profile with the cache disabled. Reload and note what blocks the
first paint. Switch to the Performance panel, enable CPU throttling, record a reload, and
find the longest task. Then run Lighthouse and read only the Largest Contentful Paint and
Cumulative Layout Shift entries with their attributions.
Now do the same to a page of your own and fix one thing — usually an unoptimised hero
image, a blocking font, or a layout shift from an image without dimensions. Re-measure to
confirm.
Spend the last twenty minutes on accessibility using the keyboard only. Unplug the mouse
and tab through your page. Can you reach every control, see where focus is, open and
close a dialogue, and submit the form? Most pages fail this within four presses. Write
down each failure with the element that caused it.
Write the audit in the form below rather than as loose notes, because a defect with a
cause and a fix attached is something you can talk about in an interview and a list of
complaints is not.
Finding Focus isnot visible on the primary navigation links
Cause A global outline reset with nothing replacing it
Impact A keyboard user cannot tell where they are, WCAG 2.4.7
Fix Restore a visible focus indicatorwith sufficient contrast
Verified Tabbed the full header again with the mouse unplugged
You finish with a before-and-after measurement of one real fix and a short keyboard-audit
list, which is a more credible artefact than another tutorial application.
What this is not
It is not web design, and calling a frontend engineer a designer or the reverse annoys
both. It is not "the easy half of full-stack" — the difficulty is differently shaped, not
smaller, and the browser has more concurrency in it than most CRUD backends. It is not
React, Next.js or any single framework, and framing your skills that way makes you look
junior in exactly the round where you cannot afford to.
It is not a discipline where the visible output tells you the quality of the work,
either. Two implementations of the same screen can be indistinguishable in a screenshot
and differ by a second of load time, by whether a keyboard user can complete the task,
and by whether the next requirement takes an afternoon or a fortnight. All three of those
are invisible until someone measures, which is why measurement is treated here as a core
skill rather than a specialism.
Nor is a component library accessibility. Adopting an accessible library removes a class
of defects and leaves the ones that matter: your focus order, your form labelling, your
error announcements, your custom widget that nobody tested with a screen reader.
It is not finished when it works on your machine, which sounds obvious and is the single
most common cause of a defect reaching a user. The environment is the variable in this
discipline, and a change that is not checked on a throttled connection, a small viewport
and a keyboard has been checked in only one of the conditions it has to survive.
And it is not a field where framework knowledge compounds. What compounds is the
platform: the layout algorithms, the event model, the caching rules, the semantics. Every
hour spent there keeps paying after the current framework has been replaced, and that is
the argument for spending your hours there deliberately rather than only when a bug
forces you to.
Frameworks are how you write frontend this year; the browser is what you are writing
for, and only one of those is still on the exam in five years.