Front end developer interviews test browser mechanics, UI architecture, and performance—not only whether you can scaffold a todo app. Expect depth on how JavaScript runs in the browser, React patterns, CSS layout, accessibility, Core Web Vitals, and live UI exercises such as autocomplete, infinite scroll, or modal dialogs.
Below are 35+ front end developer interview questions covering HTML, CSS, browser JavaScript, React, performance, accessibility, machine coding, and UI architecture. For computer networks interview questions (HTTP, DNS, TLS, TCP), see computer networks interview questions. For dedicated CSS interview questions and html and css interview questions depth (box model, specificity, flexbox, grid, modern CSS), see CSS interview questions. For TypeScript interview questions (generics, utility types, narrowing, satisfies), see TypeScript interview questions. For basic React JS interview questions, see React interview questions and answers. For interview questions on React JS for experienced and scenario-based senior prep, see React JS interview questions for experienced developers. For Angular-specific depth (signals, RxJS, standalone components), see Angular developer interview questions. For Selenium UI automation (locators, waits, DOM timing), see Selenium interview questions. For API design and full-stack integration, see full stack developer interview questions.
Interview context and how to prepare
What front end interviews test
Front end interviews test whether you can build user interfaces that are correct, usable, accessible, performant, and maintainable.
| Level | What interviewers focus on |
|---|---|
| Junior | HTML semantics, CSS basics, JavaScript fundamentals, DOM APIs, simple React components |
| Mid-level | Hooks, state management, forms, accessibility, debugging, API integration, CSS architecture |
| Senior | UI architecture, performance, Core Web Vitals, design systems, trade-offs, testing strategy, cross-team decisions |
Common areas tested:
- HTML/CSS fundamentals — semantic HTML, box model, flexbox, grid, responsive design
- JavaScript — closures, promises, async/await, event loop, scope, equality, DOM events
- Framework skills — React hooks, component design, rendering behavior, state flow
- UI quality — accessibility, keyboard navigation, loading/error states, edge cases
- Performance — LCP, INP, CLS, bundle size, lazy loading, rendering cost
- Communication — explaining trade-offs and debugging approach clearly
In modern front end interviews, many companies also include machine coding rounds where you build a component or small UI in 45–60 minutes. Examples include autocomplete, tabs, modal, accordion, pagination, infinite scroll, or a small dashboard widget.
DSA basics can still appear in screens, but front end interviews usually care more about practical UI implementation than pure algorithm trivia.
What formats should you expect
Frontend interview processes commonly combine several of these formats, depending on company size and seniority.
| Round | What it tests |
|---|---|
| Online assessment | JavaScript fundamentals, small UI tasks, basic logic |
| Technical interview | HTML, CSS, JavaScript, React, browser behavior |
| Live coding / machine coding | Build a component or widget from scratch |
| Front-end system design | Senior-level UI architecture and trade-offs |
| Behavioral round | Collaboration, ownership, debugging, design handoff |
Common machine-coding prompts:
- Autocomplete search box
- Tabs component
- Modal dialog
- Todo list with filters
- Infinite scroll feed
- Data table with sorting/filtering
- Star rating component
- Image carousel
For senior roles, expect architecture questions such as:
- Design a Twitter-like feed
- Design a component library
- Design a dashboard with real-time updates
- Design a design system for multiple teams
- Design an analytics-heavy web app
A strong candidate does not only make the UI work. They also discuss accessibility, loading states, error states, performance, testing, and maintainability.
Realistic 4–5 week prep plan
A realistic front end prep plan should balance fundamentals, React, UI coding, accessibility, and performance.
| Week | Focus | Output |
|---|---|---|
| 1 | HTML semantics, CSS box model, flexbox, grid, responsive layouts | Rebuild 2–3 common layouts |
| 2 | JavaScript fundamentals — closures, promises, event loop, equality, classes | Solve small JS logic and DOM tasks |
| 3 | React hooks, state, props, forms, effects, component composition | Build one medium React component |
| 4 | Accessibility, performance, Core Web Vitals, testing basics | Improve one UI for keyboard, screen reader, and speed |
| 5 | Machine coding + mock interviews + portfolio walkthrough | Complete 3–5 timed UI drills |
Further reading:
The highest-ROI practice is to build one polished UI that is responsive, accessible, tested, and handles loading/error/empty states.
That is a stronger interview signal than memorizing many isolated questions.
Modern React topics to revise
For modern front end interviews, prepare both React fundamentals and current React patterns.
| Area | Topics |
|---|---|
| React fundamentals | state, effects, refs, context, rendering, keys |
| Concurrent UI | useTransition, useDeferredValue |
| React 19 | Actions, useActionState, useOptimistic, use(), Server Components |
| React 19.2 | <Activity>, useEffectEvent, cacheSignal, SSR/PPR improvements |
| Optimization tooling | React Compiler |
React Compiler is now stable, but remains an optional build-time tool rather than "a React 19 hook."
Interviewers still expect strong fundamentals:
useStateuseEffectuseMemouseCallbackuseRef- controlled vs uncontrolled components
- keys and reconciliation
- prop drilling vs context
- component composition
Modern React interviews still start with rendering, state, effects, and component design. I also know React 19's Actions and Server Component model, React 19.2 features such as useEffectEvent, and how the optional React Compiler changes the need for manual memoization.
Front end vs full stack interview
Front end and full stack interviews overlap, but the depth is different.
| Area | Front end interview | Full stack interview |
|---|---|---|
| UI implementation | Deep | Moderate |
| HTML/CSS | Deep | Basic to moderate |
| Browser rendering | Deep | Moderate |
| React/component design | Deep | Moderate |
| Accessibility | Important | Sometimes lighter |
| Performance | LCP, INP, CLS, bundle size, rendering | API latency, database, caching |
| Backend/API design | Basic to moderate | Deep |
| SQL/databases | Usually lighter | More important |
| Deployment | Front-end build/CDN basics | Full app deployment |
Front end loops go deeper on:
- Browser rendering and paint
- CSS specificity and layout systems
- Component API design
- Design systems
- Accessibility
- Responsive behavior
- Client-side performance
- State management trade-offs
Full stack loops spend more time on APIs, databases, authentication, backend architecture, and deployment.
See full stack guide for that path.
HTML and semantic markup
Why does semantic HTML matter in interviews?
What interviewers are testing: Whether you choose elements for built-in semantics and behavior—not just visual appearance—and know when native HTML eliminates custom ARIA/JavaScript.
Semantic HTML means using the right element for the job instead of using div and span everywhere.
Examples:
| Use case | Prefer | Avoid |
|---|---|---|
| Page header | header |
Generic div |
| Main content | main |
Generic div |
| Navigation | nav |
Generic div |
| Article/card content | article or section |
Generic div |
| Click action | button |
Clickable div |
Why it matters:
- Accessibility — landmarks and native controls help screen readers and keyboard users.
- SEO and structure — crawlers can better understand page hierarchy and content areas.
- Maintainability — the markup explains intent to other developers.
- Less JavaScript — native elements already support many expected behaviors.
A common interview task is to refactor a “div-soup” login form into semantic, accessible markup.
A strong answer is:
I use semantic HTML first because it gives accessibility and browser behavior for free. ARIA should enhance semantics, not replace the correct HTML element.
What belongs in document head for performance and SEO?
What interviewers are testing: Whether you distinguish essential document metadata from resource hints and can optimize critical-resource discovery without cargo-culting preload/preconnect.
The document head contains metadata and resource hints that help browsers, search engines, and social platforms understand the page.
Important items:
<title>— unique page title- Meta description — short search-result summary
- Viewport meta — responsive layout on mobile
- Canonical URL — preferred version of the page
- Open Graph / social tags — better sharing previews
- Favicon and app icons
- Preload only resources whose discovery would otherwise be late, such as a known LCP image or critical font when measurement justifies it
- Preconnect for important third-party origins such as CDN, fonts, or API domains
For performance, connect this to LCP. If the hero image or main heading font is discovered late, the page may render slowly.
Be careful:
- Do not preload too many resources.
- Use
preconnectonly for important origins. - Make sure canonical URLs are correct.
- Avoid blocking critical rendering with unnecessary scripts.
A strong answer is:
I use the head for metadata, responsive behavior, canonical/social tags, and carefully chosen resource hints. For performance, I prioritize early discovery of LCP resources without over-preloading.
How do you build an accessible form?
What interviewers are testing: Whether you build forms from native labels and controls, manage validation/error associations, and preserve keyboard/focus behavior.
An accessible form should be usable with a keyboard, screen reader, and clear visual feedback.
Key practices:
- Pair every input with a visible
<label> - Use
forandidto connect labels to inputs - Do not use placeholder text as the only label
- Use
aria-describedbyfor help text and error messages - Show visible focus styles with
:focus-visible - Keep tab order logical
- Mark required fields clearly
- Announce validation errors with
role="alert"or a live region when needed - Use the right input type, such as
email,tel,number, orpassword
Common mistake:
“Placeholder text disappears when users type and may not work well as an accessible label.”
A strong answer is:
I start with native form controls and visible labels, then connect helper text and errors using
aria-describedby. I also test keyboard navigation and error announcement.
CSS layout and architecture
Explain the CSS box model and box-sizing.
What interviewers are testing: Whether you can explain the CSS box model and box-sizing. with enough depth that a follow-up 'why?' or 'what breaks?' does not stall you.
The CSS box model describes how an element’s size is calculated.
From inside to outside:
- Content
- Padding
- Border
- Margin
By default, width applies only to the content box. That means padding and border are added on top of the declared width.
box-sizing: border-box makes layout easier because the declared width includes content, padding, and border.
Example interview explanation:
“Without
border-box, an element withwidth: 100%plus padding can overflow its container. Withborder-box, the padding is included inside the 100% width.”
This is why many projects apply box-sizing: border-box globally.
A strong answer is:
The box model is content, padding, border, then margin. With the default content-box, declared width covers only content; with border-box, padding and border fit inside the declared width, which makes responsive sizing more predictable.
Flexbox vs CSS Grid — when do you use each?
What interviewers are testing: Whether you can contrast Flexbox and CSS Grid — when do you use each with trade-offs and a concrete example of when each is the right choice.
Use Flexbox for one-dimensional layouts and CSS Grid for two-dimensional layouts.
| Layout need | Better choice |
|---|---|
| Navbar items in a row | Flexbox |
| Centering content | Flexbox |
| Button group | Flexbox |
| Page shell with sidebar and content | Grid |
| Dashboard cards in rows and columns | Grid |
| Complex responsive layout | Grid |
A practical rule:
- Use Grid for the page or section layout.
- Use Flexbox inside components.
A strong answer is:
Flexbox is best when I mainly care about flow in one direction. Grid is best when I need control over rows and columns together.
How does CSS specificity work?
What interviewers are testing: Whether you can identify why a declaration wins using the cascade rather than treating specificity or !important as the whole algorithm.
Specificity compares selectors within the same relevant cascade context. IDs outweigh classes/attributes/pseudo-classes, which outweigh type selectors. Inline styles have their own precedence. !important changes cascade priority; it is not part of the specificity score.
The cascade resolves things such as:
- Origin
- Importance
- Cascade layers
- Specificity
- Scoping and source-order rules
Common interview debugging question:
“Why does my utility class not override component CSS?”
Things to check:
- Is the component selector more specific?
- Does the rule appear later in the stylesheet?
- Is
!importantinvolved? - Is the rule inside a lower-priority
@layer? - Is inline style overriding it?
Modern CSS can use @layer to organize styles such as reset, base, components, and utilities. This helps large codebases and design systems avoid specificity wars.
A strong answer is:
I debug CSS conflicts by checking cascade order, specificity, source order, and layers before adding
!important.
How do you approach responsive design?
What interviewers are testing: Whether you build fluid layouts first and choose media vs container queries based on whether the page or component owns the responsive decision.
I approach responsive design by making layouts flexible first, then adding breakpoints only where the design actually needs them.
Good practices:
- Start mobile-first
- Use relative units where appropriate
- Use Flexbox and Grid for fluid layouts
- Use
clamp()for fluid typography - Use responsive images with
srcsetandsizes - Use container queries when a component should respond to parent width
- Test keyboard and touch behavior across screen sizes
- Avoid fixed heights that break with longer content
Media queries respond to the viewport. Container queries respond to the size or state of a parent container, which is useful for reusable components.
Senior-level discussion:
| Topic | Trade-off |
|---|---|
| Tailwind | Fast utility workflow, but class-heavy markup |
| CSS Modules | Scoped styles, but less design-token structure by default |
| Design tokens | Consistency across teams, but need governance |
| Component library | Reuse and consistency, but can slow custom UI work |
A strong answer is:
I prefer fluid layouts and mobile-first CSS, then use media or container queries where the component actually needs a layout change.
What CSS choices hurt performance?
What interviewers are testing: Whether you distinguish CSS/rendering cost from JavaScript layout thrashing and prioritize measurable issues such as CLS, large stylesheets, paint, and layout work.
CSS performance issues usually come from layout shifts, heavy rendering work, unused styles, or JavaScript forcing repeated layout calculations.
Common problems:
- Large unused CSS shipped to the browser
- Animating layout-affecting properties such as
width,height,top, orleft - Not reserving space for images, ads, or dynamic content
- Loading blocking CSS late or inefficiently
- Excessive style recalculation in very large pages
- JavaScript layout thrashing from repeated DOM reads and writes
Better choices:
- Animate
transformandopacitywhen possible - Reserve image and ad space to reduce CLS
- Remove or split unused CSS
- Keep critical CSS small
- Batch DOM reads and writes
- Avoid unnecessary deep selector complexity in large apps
A strong answer is:
For CSS performance, I focus on reducing unused CSS, avoiding layout shifts, and using compositor-friendly animations such as
transformandopacity.
JavaScript in the browser
How does the browser JavaScript event loop work?
What interviewers are testing: Whether you can predict execution order between synchronous code, tasks, Promise microtasks, and browser rendering, and connect long main-thread work to poor interaction responsiveness.
The browser JavaScript event loop coordinates synchronous code, async callbacks, rendering, and user interactions.
A simple explanation:
- Synchronous code runs on the call stack.
- Browser APIs handle async work such as timers, events, and network requests.
- Completed async work is queued as a task or microtask.
- Microtasks run before the browser moves to the next task.
- The browser gets chances to render between event loop turns.
Common examples:
| Source | Queue type |
|---|---|
setTimeout() |
Task / macrotask |
| DOM event callback | Task / macrotask |
Promise.then() |
Microtask |
queueMicrotask() |
Microtask |
That is why Promise.then() usually runs before setTimeout(..., 0).
In front end interviews, the key point is that most browser UI JavaScript and DOM work executes on the main thread. Web Workers can execute JavaScript off-main-thread, although workers cannot directly manipulate the DOM. Long synchronous work on the main thread can block rendering and user input.
A strong answer is:
The call stack runs sync code first. Promise callbacks go to the microtask queue, which drains before the next task. For UI work, I avoid blocking the main thread because it hurts responsiveness.
What is a closure and why do interviewers ask?
What interviewers are testing: Whether you can define a closure and why do interviewers ask precisely and connect it to when it matters in real systems—not a one-line textbook definition.
A closure is when a function remembers variables from its outer scope even after the outer function has finished running.
Closures are common in front end code because event handlers, callbacks, and utility functions often need to remember state.
Common uses:
- Event handlers
- Debounce and throttle functions
- Private state
- Module pattern
- Function factories
- React hooks and callbacks
Classic interview example:
A loop using var may cause every callback to share the same variable. Using let creates a new block-scoped variable for each loop iteration.
Interviewers ask closures because they test whether you understand scope, async callbacks, and state.
A strong answer is:
A closure lets an inner function keep access to variables from its outer scope. It is useful for callbacks, event handlers, and utilities like debounce.
Explain prototypal inheritance in JavaScript.
What interviewers are testing: Whether you can explain prototypal inheritance in JavaScript. with enough depth that a follow-up 'why?' or 'what breaks?' does not stall you.
JavaScript uses prototypal inheritance. Objects can delegate property lookup to another object through their prototype chain.
If a property is not found on the object itself, JavaScript looks up the prototype chain until it finds the property or reaches null.
Important points:
- Every normal object has an internal prototype link.
Object.create()can create an object with a chosen prototype.instanceofchecks whether a constructor’s prototype appears in an object’s prototype chain.classsyntax is mostly cleaner syntax over JavaScript’s prototype-based model.
Example interview explanation:
“In JavaScript, inheritance is based on objects delegating to other objects. Classes make the syntax familiar, but under the hood objects still use prototypes.”
See javascript instanceof for related checks.
A strong answer is:
“In JavaScript, inheritance is based on objects delegating to other objects. Classes make the syntax familiar, but under the hood objects still use prototypes.”
How does this behave in JavaScript?
What interviewers are testing: Whether you know that normal-function this is determined by the call site while arrow functions capture lexical this, and can diagnose lost-context bugs in callbacks and methods.
In JavaScript, this depends mainly on how a function is called, not where it is written.
Common rules:
| Call style | this value |
|---|---|
| Method call | Object before the dot |
Constructor with new |
Newly created object |
call, apply, bind |
Explicitly provided value |
| Arrow function | Lexical this from surrounding scope |
| Standalone function | undefined in strict mode, otherwise global object |
Common mistakes:
- Passing an object method as a callback and losing
this - Expecting arrow functions to have their own
this - Mixing class methods and event handlers without binding
A strong answer is:
For normal functions,
thisis decided by the call site. Arrow functions do not create their ownthis; they capture it from the surrounding scope.
Explain event bubbling, capturing, and delegation.
What interviewers are testing: Whether you can explain event bubbling, capturing, and delegation. with enough depth that a follow-up 'why?' or 'what breaks?' does not stall you.
Browser events move through three phases:
- Capturing phase — event travels from the document down toward the target.
- Target phase — event reaches the actual target element.
- Bubbling phase — event bubbles back up through ancestors.
stopPropagation() stops the event from continuing through the propagation path.
Event delegation means attaching one listener to a parent and handling events from child elements using event.target.
This is useful for:
- Large lists
- Dynamic items added later
- Reducing many repeated event listeners
list.addEventListener("click", (event) => {
const item = event.target.closest("[data-id]");
if (!item || !list.contains(item)) {
return;
}
handleSelect(item.dataset.id);
});The list.contains(item) check avoids accidentally handling a matching element outside the intended parent.
A strong answer is:
Events capture down, reach the target, then bubble up. Delegation uses bubbling so a parent can handle child events efficiently.
How do you fetch data and handle errors in the browser?
What interviewers are testing: Whether you handle loading, empty, success, HTTP, and network error states separately and prevent stale responses from updating the UI.
I would use fetch() with async/await, but I would handle more than just the happy path.
Important points:
- Show a loading state while the request is pending.
- Check
response.okbecause HTTP errors like 404 or 500 do not automatically reject the fetch promise. - Catch network errors.
- Handle empty states separately from error states.
- Use
AbortControllerto cancel stale requests when users navigate, type quickly, or change filters. - Avoid updating UI from an old response after a newer request finishes first.
Example structure:
const controller = new AbortController();
try {
const response = await fetch("/api/products", {
signal: controller.signal,
});
if (!response.ok) {
throw new Error("Request failed");
}
const data = await response.json();
renderProducts(data);
} catch (error) {
if (error.name !== "AbortError") {
renderError();
}
}A strong answer is:
I handle loading, empty, success, HTTP errors, and network errors separately. For rapidly changing requests I cancel obsolete work with
AbortControllerand ensure only the latest request is allowed to update the UI.
Implement debounce vs throttle — common live-coding ask.
What interviewers are testing: Whether you can contrast Implement debounce and throttle — common live-coding ask. with trade-offs and a concrete example of when each is the right choice.
Debounce and throttle both limit how often a function runs, but they solve different problems.
| Technique | Meaning | Common use |
|---|---|---|
| Debounce | Run after the user stops triggering events | Search input, autocomplete, resize end |
| Throttle | Run at most once per interval | Scroll handler, mousemove, resize progress |
Debounce example:
function debounce(fn, delay) {
let timerId;
return (...args) => {
clearTimeout(timerId);
timerId = setTimeout(() => {
fn(...args);
}, delay);
};
}In interviews, also explain the trade-off:
- Debounce reduces unnecessary work after rapid input.
- Throttle keeps updates happening at a controlled rate.
- Both can help reduce main-thread work and improve responsiveness.
- They do not fix expensive rendering by themselves; you still need to optimize the actual work.
A strong answer is:
I use debounce when I only care about the final value after the user pauses. I use throttle when I need regular updates but want to limit frequency.
React and modern UI libraries
What is the virtual DOM and reconciliation?
What interviewers are testing: Whether you can define the virtual DOM and reconciliation precisely and connect it to when it matters in real systems—not a one-line textbook definition.
The virtual DOM is React’s in-memory representation of the UI.
When state or props change, React creates a new UI tree, compares it with the previous tree, and decides what needs to change in the real DOM. This process is called reconciliation.
Important points:
- React updates the DOM efficiently, but not magically for free.
- Stable component structure and stable keys help reconciliation.
- Expensive renders can still hurt performance if components do too much work.
- Modern React can prioritize urgent updates, such as typing or clicking, over less urgent UI work.
A strong answer is:
React uses reconciliation to compare the previous and next UI trees and update the browser DOM efficiently. But performance still depends on good state design, stable keys, and avoiding unnecessary expensive renders.
What are the rules of hooks?
What interviewers are testing: Whether you understand stable Hook call order and know that React's use() API is a special exception with its own restrictions.
Most Hooks must be called unconditionally at the top level of a component or custom Hook so React sees the same Hook order on every render. React's use() API is a special exception: it can be called in conditions and loops, but still must be used from a component or Hook and follow its documented restrictions.
Call ordinary hooks only from React function components or custom hooks—not from event handlers or plain JavaScript functions.
Why this matters:
React tracks hook state by call order. If hooks run in a different order between renders, React cannot correctly match state to each hook.
A strong answer is:
Most Hooks depend on stable call order, so I keep them at the top level.
use()is a special React API that may be called conditionally, so I don't blindly apply the ordinary Hook-order rule to it.
What are common useEffect mistakes?
What interviewers are testing: Whether you can define common useEffect mistakes precisely and connect it to when it matters in real systems—not a one-line textbook definition.
Common useEffect mistakes include:
- Missing dependencies → stale values
- Creating unstable object/function dependencies that cause unnecessary re-synchronization
- No cleanup for timers, subscriptions, or event listeners
- Fetching data without aborting stale requests
- Using effects for derived state that could be calculated during render
- Putting too much business logic inside effects
For data fetching, modern React interviews often expect this distinction:
| State type | Better tool |
|---|---|
| Local UI state | useState, useReducer |
| Server/cache state | React Query, SWR, framework loader, or server-side data fetching |
useEffectEvent is for logic conceptually triggered from an Effect that needs latest values without making those values Effect dependencies; it is not an escape hatch for silencing the dependency linter.
A strong answer is:
I use
useEffectfor synchronizing with external systems, not for every calculation. For server state, I prefer a data-fetching library or framework pattern that handles caching, refetching, and stale requests.
When do you use Context, Redux, Zustand, or React Query?
What interviewers are testing: Whether you can name decision criteria for do you use context, redux, zustand, or react query instead of a blanket always/never rule.
State management depends on what kind of state you are managing.
| Tool | Best for |
|---|---|
| useState | Simple local component state |
| useReducer | Complex local state transitions |
| Context | Low-frequency global values such as theme, locale, auth user |
| Zustand | Lightweight shared client state |
| Redux Toolkit | Large apps with complex shared state, strict patterns, debugging needs |
| React Query / SWR | Server state: cache, refetch, dedupe, loading/error states |
Important distinction:
- Client state lives in the browser and is controlled by the UI.
- Server state comes from APIs and needs caching, refetching, invalidation, and synchronization.
A strong answer is:
I do not put everything into global state. I keep state local when possible, use Context for low-frequency global values, use a client-state library when state is complex, and use React Query or SWR for server state.
When should you use React.memo, useMemo, and useCallback?
What interviewers are testing: Whether you can name decision criteria for should you use react.memo, usememo, and usecallback instead of a blanket always/never rule.
Use memoization when profiling shows avoidable re-renders or expensive calculations.
| Tool | Use case |
|---|---|
| React.memo | Skip re-rendering a component when props are unchanged |
| useMemo | Cache an expensive calculated value |
| useCallback | Keep a function reference stable when passing it to memoized children |
Do not memoize everything by default.
Problems with over-memoization:
- More complex code
- Harder debugging
- Extra memory usage
- Little or no benefit if the component is cheap
Modern React tooling, including React Compiler, can reduce the need for manual memoization in supported setups. But candidates should still understand rendering, props, state, and expensive work.
A strong answer is:
I profile first. I use memoization when a component is expensive, props are stable, or a callback causes unnecessary child renders. Memoization is not my default starting point.
What are React Server Components (RSC)?
What interviewers are testing: Whether you can define React Server Components (RSC) precisely and connect it to when it matters in real systems—not a one-line textbook definition.
React Server Components use a server-oriented component model whose rendered result can be composed with Client Components and does not ship the Server Component's JavaScript to the browser.
Server Components and SSR are different concepts. SSR renders HTML for the initial response; Server Components may run ahead of time during build or per request in a separate server environment.
Key points:
- They can fetch server-side data directly.
- Their component JavaScript is not shipped to the browser.
- They cannot use browser-only APIs such as
windowordocument. - They cannot use client-only hooks such as
useStateoruseEffect. - They can be composed with Client Components for interactivity.
Use Server Components for:
- Data-heavy pages
- Static or mostly static UI
- Reducing client JavaScript
- Keeping server-only logic off the client
Use Client Components for:
- Click handlers
- Forms with client-side state
- Browser APIs
- Interactive widgets
- Effects and subscriptions
A strong answer is:
Server Components reduce client-side JavaScript by rendering non-interactive parts on the server. For interactivity, I compose them with Client Components at clear boundaries.
Why do lists need stable keys in React?
What interviewers are testing: Whether you can justify Why do lists need stable keys in React with technical and business reasoning interviewers can probe deeper on.
React uses keys to identify list items across renders.
Stable keys help React preserve the right component state when items are added, removed, filtered, or reordered.
Bad keys:
Math.random()- Array index for reorderable lists
- Values that change between renders
Good keys:
- Database ID
- Product ID
- User ID
- Stable slug or unique key from data
Example problem:
If you use array index as the key in a reorderable list, React may keep the wrong input state with the wrong row after sorting.
A strong answer is:
Keys should be stable and unique among siblings. They help React match items correctly during reconciliation and avoid state bugs.
Performance and Core Web Vitals
Explain LCP, INP, and CLS.
What interviewers are testing: Whether you can explain LCP, INP, and CLS. with enough depth that a follow-up 'why?' or 'what breaks?' does not stall you.
Core Web Vitals measure loading speed, responsiveness, and visual stability.
| Metric | Measures | Good target |
|---|---|---|
| LCP | Largest Contentful Paint: main content loading speed | <= 2.5s |
| INP | Interaction to Next Paint: responsiveness to user interactions | <= 200ms |
| CLS | Cumulative Layout Shift: unexpected layout movement | <= 0.1 |
Important distinction:
- LCP is about how quickly the main content appears.
- INP is about how quickly the page responds to interactions.
- CLS is about whether the layout jumps unexpectedly.
INP replaced FID as the responsiveness Core Web Vital, so candidates should avoid giving outdated FID-only answers.
For field data, these "good" thresholds are evaluated at the 75th percentile of visits, not from one Lighthouse run.
A strong answer is:
LCP measures loading, INP measures interaction responsiveness, and CLS measures visual stability. For front end interviews, I connect each metric to a real fix, not just the definition.
How do you improve LCP on a marketing page?
What interviewers are testing: Whether you diagnose the actual LCP element and optimize its server response, discovery, download, and render delay rather than applying random Lighthouse recommendations.
To improve LCP, first identify the LCP element. On a marketing page, it is often the hero image, hero heading, or large banner.
Common fixes:
- Compress and resize the hero image
- Use modern formats such as WebP or AVIF
- Use responsive images with
srcsetandsizes - Preload the LCP image when appropriate
- Use
fetchpriority="high"for the main hero image when appropriate - Reduce server response time with caching or CDN
- Remove unnecessary render-blocking JavaScript
- Load critical CSS early
- Avoid late-loading fonts that block the main heading
Measure with:
- Lighthouse
- PageSpeed Insights
- Chrome DevTools Performance panel
- CrUX or other field data
A strong answer is:
I would first identify the actual LCP element, then optimize its discovery, download, and render path. For a marketing page, that often means optimizing the hero image, critical CSS, fonts, and server response time.
How do you improve INP?
What interviewers are testing: Whether you can trace an interaction through input delay, event-handler work, and presentation delay and remove long main-thread tasks.
To improve INP, reduce the time between a user interaction and the next visual response.
Common fixes:
- Break up long JavaScript tasks
- Reduce expensive work inside click, input, and key handlers
- Debounce or throttle high-frequency handlers
- Avoid large synchronous JSON parsing during interactions
- Use
useTransitionfor non-urgent React updates—transitions change scheduling priority; they do not make expensive JavaScript computation cheap - Use
useDeferredValuefor expensive UI updates from fast-changing input - Move heavy work to Web Workers when appropriate
- Reduce unnecessary re-renders
- Keep the DOM smaller where possible
Example:
If clicking a filter button triggers a huge list recalculation, the UI may feel frozen. You can improve INP by splitting work, virtualizing the list, memoizing measured bottlenecks, or deferring non-urgent updates. Long CPU work may still need algorithmic improvement, chunking, virtualization, or a Web Worker—useTransition does not make expensive computation cheap.
A strong answer is:
INP improves when the main thread is free to respond quickly. I would profile the interaction, find long tasks, and reduce or defer expensive work.
What is the difference between CSR, SSR, SSG, and framework patterns such as ISR?
What interviewers are testing: Whether you can state the defining distinction between csr, ssr, ssg, and isr and give a scenario where choosing wrong hurts production.
These are different rendering strategies for web applications.
| Pattern | Where rendered | When to use |
|---|---|---|
| CSR | Browser | Highly interactive dashboards behind login |
| SSR | Server per request | Personalized pages, dynamic SEO pages |
| SSG | Build time | Static marketing pages, docs, blogs |
| ISR | Framework-level static regeneration with revalidation rules | Large content sites that change occasionally |
Important details:
- CSR can have slower first content if the browser must download and run a lot of JavaScript first.
- SSR can improve initial HTML and SEO, but it may increase server work.
- SSG is fast and cacheable, but content updates usually require rebuilds.
- ISR is a framework-level static regeneration strategy in which previously generated pages can be refreshed after deployment according to revalidation rules.
- SSR/SSG HTML may still need hydration before interactive components work.
A strong answer is:
I choose the rendering strategy based on freshness, personalization, SEO, cacheability, and hydration cost.
How do you reduce JavaScript bundle size?
What interviewers are testing: Whether you measure bundle composition first and make targeted dependency/code-splitting decisions without fragmenting the app into excessive lazy chunks.
To reduce JavaScript bundle size, first measure what is inside the bundle.
Common fixes:
- Route-based code splitting
- Component-level lazy loading
- Dynamic
import() - Remove unused dependencies
- Replace heavy libraries with smaller alternatives
- Use tree-shaking-friendly imports
- Avoid importing entire utility libraries for one function
- Split vendor bundles where useful
- Keep heavy server-only logic out of the client bundle
- Use Server Components where appropriate
- Analyze bundles with tools such as webpack-bundle-analyzer, source-map-explorer, or Vite visualizer
Senior-level points:
- Set performance budgets in CI
- Track bundle size changes in pull requests
- Measure both lab and field impact
- Avoid hurting UX with excessive lazy loading
A strong answer is:
I start with bundle analysis, remove or split the biggest costs, and set performance budgets so bundle size does not regress silently.
Accessibility and UX
When do you use ARIA vs native HTML?
What interviewers are testing: Whether you know when native HTML already provides semantics/behavior and can implement keyboard/focus behavior when a custom ARIA widget is genuinely necessary.
Use native HTML first.
Native elements such as button, input, select, label, form, and dialog already include built-in browser behavior, keyboard support, and accessibility semantics.
Prefer native <dialog> when it satisfies the product/browser requirements. If building a custom dialog pattern, implement the required dialog semantics and focus behavior correctly rather than adding role="dialog" alone.
Use ARIA when native HTML is not enough, especially for custom widgets such as:
- Combobox
- Tabs
- Accordion
- Custom menu
- Custom listbox
Common ARIA examples:
| Need | ARIA |
|---|---|
| Expanded/collapsed state | aria-expanded |
| Relationship between trigger and panel | aria-controls |
| Current active option | aria-activedescendant |
| Modal context | aria-modal |
| Helper or error text | aria-describedby |
Important rule:
Bad ARIA can be worse than no ARIA.
For modals, interviewers expect more than role="dialog". You should discuss:
- Move focus into the modal when it opens
- Trap focus while the modal is open
- Close with Escape where appropriate
- Restore focus to the trigger when closed
- Prevent background content from being interacted with
A strong answer is:
I prefer native HTML first. I use ARIA only when building custom interactions, and I test keyboard behavior, screen reader semantics, and focus management.
What WCAG concepts should front end developers know?
What interviewers are testing: Whether you can translate WCAG principles into concrete frontend implementation and testing decisions rather than reciting POUR.
Front end developers do not need to memorize every WCAG success criterion, but they should understand the four main principles.
| Principle | Meaning | Front end examples |
|---|---|---|
| Perceivable | Users can perceive the content | Alt text, captions, color contrast |
| Operable | Users can operate the interface | Keyboard access, focus states, no keyboard traps |
| Understandable | UI and errors are clear | Labels, instructions, predictable behavior |
| Robust | Works across browsers and assistive tech | Valid markup, semantic HTML, correct ARIA |
Important examples to know:
- Normal text contrast should meet common accessibility contrast expectations
- Interactive elements should be keyboard reachable
- Focus should not be hidden or trapped incorrectly
- Form errors should be clear and associated with inputs
- Touch/click targets should be usable
- Do not rely only on color to communicate meaning
Testing tools:
- Browser keyboard testing
- Screen reader smoke testing
- axe DevTools
- Lighthouse accessibility checks
- Playwright accessibility assertions where useful
A strong answer is:
I use WCAG as a practical checklist: can users perceive, operate, understand, and reliably use the UI across devices and assistive technologies?
Machine coding and system design (UI)
How would you build a search autocomplete component?
What interviewers are testing: Whether you can walk through a structured, spoken approach to how would you build a search autocomplete component—naming entities, trade-offs, and failure modes without jumping to code first.
First, clarify the requirements.
Questions to ask:
- Should results load from local data or an API?
- What debounce delay is expected?
- Should keyboard navigation be supported?
- What happens on empty, loading, and error states?
- Should clicking outside close the menu?
- Should the first result be highlighted automatically?
- How should stale API responses be handled?
Implementation approach:
- Use a controlled input.
- Debounce the search query.
- Fetch results after the debounce delay.
- Abort stale requests using
AbortController. - Show loading, error, empty, and success states.
- Support keyboard navigation with ArrowUp, ArrowDown, Enter, and Escape.
- Use an accessible combobox/listbox pattern.
- Highlight matched text if required.
Accessibility points:
- Input should have a clear label
- Results should be announced appropriately
- Active option should be tracked
- Keyboard and mouse behavior should match user expectations
A strong answer is:
I use a controlled input, debounce API requests, cancel or ignore stale responses, and expose loading/error/empty states. Results follow the accessible combobox pattern with keyboard navigation for arrows, Enter, and Escape.
How do you implement infinite scroll performantly?
What interviewers are testing: Whether you can combine pagination, Intersection Observer, request deduplication, virtualization, focus/navigation considerations, and an accessible fallback.
For infinite scroll, I would use an Intersection Observer with a sentinel element near the bottom of the list.
Key practices:
- Fetch the next page when the sentinel enters the viewport
- Prevent duplicate requests while loading
- Keep track of pagination cursor or page number
- Show loading and error states
- Stop requesting when there are no more results
- Virtualize very long lists using tools such as
react-window - Preserve scroll position when users navigate back
- Reserve space for loading content to reduce layout shift
Trade-offs:
| Approach | Pros | Cons |
|---|---|---|
| Infinite scroll | Smooth browsing experience | Harder for accessibility, SEO, and footer access |
| Load more button | More controlled and accessible | Slightly more manual user action |
| Pagination | Best for SEO and direct navigation | Less fluid experience |
A strong answer is:
I would use Intersection Observer for loading, virtualization for long lists, and consider a Load more button when accessibility or SEO matters.
How would you design a component library for 10+ product teams?
What interviewers are testing: Whether you can walk through a structured, spoken approach to how would you design a component library for 10+ product teams—naming entities, trade-offs, and failure modes without jumping to code first.
For a shared component library, I would design for consistency, accessibility, versioning, and adoption.
Core pieces:
- Design tokens — color, spacing, typography, radius, shadow, motion
- Primitive components — Button, Input, Modal, Tooltip, Tabs, Select
- Accessible defaults — keyboard support, focus states, labels, ARIA where needed
- Variant API — size, intent, state, density, icon support
- Documentation — Storybook, usage examples, do/don’t guidelines
- Theming — brand or product-level customization
- Testing — unit, interaction, accessibility, visual regression
- Versioning — semantic versioning and changelog
- Migration support — codemods or deprecation warnings for breaking changes
Senior-level trade-offs:
| Decision | Trade-off |
|---|---|
| Flexible API | Powerful but harder to govern |
| Strict API | Consistent but may block edge cases |
| Central ownership | Higher quality but slower delivery |
| Federated contribution | Faster adoption but needs review process |
A strong answer is:
I would build accessible primitives, document clear usage patterns, version changes carefully, and create a contribution process so teams can adopt the system without forking it.
Testing, tooling, and behavioral
How do you test front end code?
What interviewers are testing: Whether you choose the cheapest test level that proves user-visible behavior and avoid coupling tests to component implementation details.
Front end testing should focus on user-visible behavior, not implementation details.
Common levels:
| Test type | Tools | What to test |
|---|---|---|
| Unit | Vitest, Jest | Pure functions, utilities, reducers |
| Component | React Testing Library | Rendering, user interactions, states |
| Integration | Testing Library, MSW | Component + API behavior |
| E2E | Playwright, Cypress | Critical user flows |
| Visual regression | Chromatic, Percy | Design system and layout changes |
Good testing practices:
- Prefer queries such as
getByRoleandgetByLabelText - Test loading, error, empty, and success states
- Mock network calls at the boundary
- Avoid testing internal state directly
- Add E2E tests for checkout, login, signup, and other critical flows
- Include accessibility checks where practical
A strong answer is:
I test what the user sees and does. I prefer role-based queries, cover important UI states, and reserve E2E tests for critical flows.
What is the role of Vite or webpack in modern front end?
What interviewers are testing: Whether you understand what the development/build pipeline actually does—transforms, module graph, HMR, code splitting, assets, and production optimization—rather than ranking Vite vs webpack by popularity.
Build tools such as Vite and webpack help convert source code into optimized files the browser can run.
They commonly handle:
- JavaScript/JSX transformation and TypeScript syntax transpilation; type checking may run as a separate build/CI step
- JSX transform
- CSS processing
- Module resolution
- Hot Module Replacement during development
- Tree shaking
- Code splitting
- Asset optimization
- Production bundling
Vite is popular because it provides a fast development server and quick HMR. For production, it creates optimized builds suitable for deployment.
Webpack is still widely used in many mature codebases and gives deep configuration control.
Interview-level answer:
“We use build tools to support modern JavaScript, TypeScript, JSX, CSS processing, dev-server HMR, code splitting, and optimized production bundles. I do not need to know every plugin, but I should understand what the build pipeline does.”
A strong answer is:
“We use build tools to support modern JavaScript, TypeScript, JSX, CSS processing, dev-server HMR, code splitting, and optimized production bundles. I do not need to know every plugin, but I should understand what the build pipeline does.”
Tell me about a UI bug you fixed in production.
What interviewers are testing: Whether you can give a specific, honest story with situation, action, and outcome—not a generic strength disguised as a weakness.
Use the STAR format: Situation, Task, Action, Result.
A strong story should include:
- User impact
- How you reproduced the issue
- Browser/device details
- Root cause
- Fix
- Test or monitoring added afterward
- What you learned
Example structure:
| STAR step | Example |
|---|---|
| Situation | Checkout button failed on Safari for some users |
| Task | Identify and fix the issue quickly |
| Action | Reproduced on BrowserStack, traced it to a CSS/flex or event-handling issue, shipped a fix |
| Result | Checkout recovered, and a regression test or monitoring alert was added |
Other good front end examples:
- CLS spike after image layout change
- Hydration mismatch in SSR page
- Race condition in fetch results
- Modal focus trap bug
- Mobile layout breaking at a specific viewport
- Third-party script blocking page interaction
A strong answer is:
I explain the user impact first, then how I reproduced, debugged, fixed, and prevented the issue from happening again.
Final-week front end interview checklist
Use the final week for timed practice, not new theory.
Checklist:
- Build autocomplete or infinite scroll from scratch
- Build one accessible modal, tabs, or dropdown component
- Explain LCP, INP, and CLS with one fix each
- Review closures, prototypes,
this, promises, and the event loop - Practice DOM events, bubbling, capturing, and delegation
- Review React hooks, keys, state ownership, and effect cleanup
- Practice one front-end system design prompt
- Prepare one production UI bug story using STAR
- Prepare a portfolio walkthrough for one polished UI project
- Check keyboard navigation and Lighthouse issues in your portfolio
Also review:
- DOM selectors
- event bubbling
- full stack guide
- Interview Questions

