What frontend interviews actually test
Frontend coding interviews are not just algorithm puzzles with a React logo on top. They test whether you understand how JavaScript really behaves, whether you can build a small interactive feature without fighting the framework, and whether you make sensible calls about state, rendering, and accessibility under time pressure. The same person who can reverse a linked list can still struggle to explain why a stale closure broke their event handler, and that gap is exactly what these rounds find.
There are three common formats. A core JavaScript round that probes language behaviour. A build round where you implement a component or small app live. And a utility round where you implement something like debounce, a small event emitter, or a promise helper from scratch. Prepare for all three, because companies mix them freely.
Get the language fundamentals solid
Before any framework, the interviewer wants to know that you understand the runtime. The topics that come up again and again are closures, the event loop, this binding, and how promises schedule work.
A classic trap is the loop with var. Be ready to explain why this logs the same number three times and how to fix it.
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// logs 3, 3, 3 because var is function scoped and the callbacks run later
Swapping var for let gives each iteration its own binding, so it logs 0, 1, 2. Being able to talk through why, in terms of scope and the event loop, is worth more than memorising the output.
Know the difference between microtasks and macrotasks well enough to predict the order of logs when promises and timeouts are mixed. Know how bind, arrow functions, and method calls change this. These come up in almost every core round.
Practise the small utilities
Implementing a utility from scratch is a favourite because it is quick to set up and reveals a lot. Debounce is the most common. Practise writing it without looking, including the part where you preserve this and the arguments.
function debounce(fn, delayMs) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delayMs);
};
}
Other utilities worth having in your fingers are throttle, a simple EventEmitter with on and emit, a deepClone, and a function that runs promises with limited concurrency. For each one, be ready to talk about edge cases: what happens if the wrapped function throws, what happens on rapid repeated calls, and how you would test it.
Building a React feature live
The build round is where most of the time goes. You will be asked to make something interactive, such as a typeahead search, a star rating, a paginated list, or a small todo app. The interviewer is watching how you structure state, how you handle async, and whether you avoid common React mistakes.
Lead with the data. Decide what state you truly need and keep it minimal. Derive everything you can rather than storing it. For a typeahead, the state is the query and the results. The loading flag and the visible suggestions are derived from those.
function useSearch(query) {
const [results, setResults] = useState([]);
useEffect(() => {
if (!query) return;
const controller = new AbortController();
fetch(`/api/search?q=${encodeURIComponent(query)}`, { signal: controller.signal })
.then((r) => r.json())
.then(setResults)
.catch(() => {});
return () => controller.abort();
}, [query]);
return results;
}
Notice the cleanup that aborts the in-flight request. Mentioning that you cancel stale requests, so an old slow response cannot overwrite a newer one, is a strong signal. So is debouncing the query before it hits the network.
Show that you understand rendering
Interviewers often probe whether you know why a component re-renders and when that matters. You do not need to reach for memoisation everywhere, and saying so is itself a good answer. Reach for it when you have measured a real cost.
Be ready to explain the dependency array of useEffect, why an object or function in that array can cause an effect to run every render, and how useCallback or useMemo stabilise those references. Be honest that premature optimisation with memo can make code harder to read for no benefit. The senior signal is knowing the tradeoff, not reciting the API.
Keys in lists come up constantly. Explain why using an array index as a key breaks when items are inserted or reordered, and why a stable id fixes it.
Do not forget accessibility and the small details
Frontend rounds reward candidates who remember that real users interact with the thing they are building. As you build, narrate the details that production code needs.
- Make interactive elements keyboard reachable and use the right semantic element, a button for an action rather than a clickable div.
- Handle the empty, loading, and error states, not only the happy path.
- Manage focus when a dialog opens or results appear, so screen reader users are not lost.
- Debounce network calls and show a sensible loading indicator.
Even a sentence or two about accessibility sets you apart, because many candidates skip it entirely.
Common mistakes to avoid
- Storing derived data in state, then fighting to keep it in sync.
- Forgetting to clean up effects, which leaks listeners or lets stale responses win.
- Reaching for a global state library when local state would do.
- Going silent. Talk through your plan and your tradeoffs so the interviewer can redirect you early.
How to practise
Build five small features end to end on a timer: a typeahead, a star rating, an accordion, a paginated table, and a todo list with filtering. Then implement five utilities from scratch. After each, review whether your state was minimal, your async was cancellable, and your component was accessible. A few weeks of this makes the build round feel routine, which is exactly the calm you want when the clock is running.
Continue your prep
Practise against real role questions and templates: