Frontend System Design

Fundamentals & Approach

1

How do you approach a frontend system design interview?

Follow a structured framework:

  1. Clarify Requirements (2-3 min)
    • Functional: What features are needed?
    • Non-functional: Scale, performance, offline support?
    • Constraints: Browser support, mobile?
  2. High-Level Design (5 min)
    • Component architecture
    • Data flow
    • Key APIs
  3. Deep Dive (15-20 min)
    • Core components
    • State management
    • Performance optimizations
  4. Trade-offs & Alternatives (5 min)
    • Discuss decisions made
    • What would you do differently at scale?

What problems does this solve?

  • Provides a reliable, repeatable framework that prevents candidates from freezing up or rambling during high-pressure whiteboard sessions.
  • Ensures that edge cases, scaling bottlenecks, and non-functional requirements are addressed before any underlying code architecture is built.
  • Demonstrates to interviewers that the candidate is a senior-level thinker who scopes problems holistically rather than jumping straight to implementation details.
2

What are the key non-functional requirements to consider?

RequirementQuestions to Ask
PerformanceLoad time targets? Bundle size limits?
ScalabilityHow many concurrent users? Data volume?
AccessibilityWCAG compliance level?
InternationalizationMulti-language? RTL support?
Offline SupportPWA requirements?
SecurityAuth method? Sensitive data handling?
SEOCrawlability important?
Browser SupportIE11? Mobile browsers?

What problems does this solve?

  • Prevents system failures by ensuring the architecture is capable of handling anticipated traffic loads, latency constraints, and data volume.
  • Guarantees international compliance and broad user adoption by enforcing requirements around accessibility (WCAG), internationalization (i18n), and security.
  • Acts as the ultimate architectural compass; identifying non-functional constraints early fundamentally dictates whether a team chooses SPA vs SSR, or GraphQL vs REST.
3

What is Component-Driven Architecture?

Breaking the UI into independent, reusable components organized in a hierarchy.

Principles:

  • Single responsibility
  • Composability
  • Isolation (own styles/logic)
  • Reusability across pages

What problems does this solve?

  • Enables massive engineering teams to work concurrently on unified applications without stepping on each other's toes or causing merge conflicts.
  • Radically reduces maintenance debt by isolating defects to single, pure components rather than unwinding monolithic global dependencies.
  • Facilitates the creation of universal Design Systems (like Storybook), keeping typography, spacing, and interaction states flawlessly consistent across the entire platform.
4

How do you decide between Client-Side and Server-Side Rendering?

FactorCSRSSRSSG
Initial loadSlowerFasterFastest
SEOPoorGoodGood
Server costLowHighLow
Dynamic contentEasyEasyHard
InteractivityImmediate*After hydrationAfter hydration

Choose:

  • CSR: Dashboards, apps behind login
  • SSR: Dynamic content + SEO (e-commerce, news)
  • SSG: Static content (blogs, docs, marketing)
  • ISR: Hybrid (Next.js Incremental Static Regeneration)

What problems does this solve?

  • Solves the "blank screen" problem for parsing bots by leveraging Server-Side Rendering (SSR) to dramatically improve search engine optimization (SEO) routing.
  • Optimizes TTFB (Time to First Byte) and reduces massive JavaScript payload bottlenecks by offloading computation-heavy DOM generation to high-powered backend servers.
  • Allows architectures to deploy blazing-fast Static Site Generation (SSG) assets via raw CDNs, effectively eliminating database latency for marketing pages.
5

What is Micro-Frontend Architecture?

Splitting a frontend into independent, deployable applications owned by different teams.

Implementation options:

  • iframes (isolated but limited)
  • Web Components
  • Module Federation (Webpack 5)
  • Import maps

Trade-offs: Autonomy vs. consistency, performance overhead.

What problems does this solve?

  • Decouples monolithic release cycles, allowing entirely separate teams (e.g., Checkout vs Profile) to deploy specialized updates securely on their own isolated cadences.
  • Mitigates catastrophic platform downtime; if the "Search" micro-frontend crashes due to a localized memory leak, the "Cart" micro-frontend remains actively functional.
  • Permits incremental legacy migrations, enabling companies to cleanly inject modern React modules into aging AngularJS platforms without requiring multi-year rewrites.

State Management

6

How do you decide on a state management approach?

State TypeSolution
Local UI stateComponent state (useState)
Shared component stateLift state up / Context
Complex app stateRedux, Zustand, Pinia
Server/async stateReact Query, SWR, Apollo
URL stateRouter params/query
Form stateReact Hook Form, Formik

Rule: Start simple, add complexity only when needed.

What problems does this solve?

  • Prevents "prop drilling" and unmanageable component coupling by introducing a single, deterministic source of truth for global session properties.
  • Radically minimizes unnecessary DOM re-renders by allowing isolated sibling components to subscribe exclusively to the tiny slices of data they independently care about.
  • Provides explicit structural boundaries between UI presentation logic and asynchronous data mutation algorithms, keeping component files clean and strictly declarative.
7

What is the Flux/Redux pattern?

Unidirectional data flow:

Redux specifics:

  • Actions: Plain objects describing what happened
  • Reducers: Pure functions that compute new state
  • Store: Single source of truth
  • Selectors: Derive data from state

When to use: Large apps with complex state interactions.

What problems does this solve?

  • Eradicates unpredictable two-way data binding bugs by enforcing a strictly unidirectional data flow that is mathematically predictable and aggressively traceable.
  • Enables transformative developer tooling like "Time Travel Debugging," allowing engineers to literally step backwards through sequential state snapshots to isolate mutations.
  • Forces teams into a robust, standardized pattern of abstracting complex business logic out of volatile UI shells into heavily testable pure reducer functions.
8

What is Server State vs. Client State?

  • Server State: Data from the backend (users, products). Needs fetching, caching, sync.
  • Client State: UI state (modals open, selected tabs). Only exists in the browser.

Insight: Many apps over-use Redux for server state when React Query is simpler.

What problems does this solve?

  • Exposes the anti-pattern of aggressively dumping volatile API payloads into global client stores (like Redux), drastically simplifying frontend architecture footprints.
  • Solves the notoriously difficult problems of caching, background refetching, and deduping identical network requests effortlessly via libraries like React Query.
  • Clearly separates ephemeral local UI preferences (like open accordion menus) from highly critical remote entity records (like user database profiles).
9

How do you handle optimistic updates?

Update the UI immediately before the server confirms, then reconcile.

What problems does this solve?

  • Creates an illusion of zero-latency performance by instantly painting successful UI mutations to the screen fully independent of the underlying network sluggishness.
  • Dramatically improves perceived user experience and deeply increases engagement metrics on critical interaction paths like "liking" a post or "adding" an item to a cart.
  • Provides graceful automated rollback mechanisms that transparently revert the UI state back to normal if the background network request silently fails or times out.
10

How do you sync state across browser tabs?

Options:

  1. BroadcastChannel API
  1. localStorage events
  1. Service Worker (for offline-first apps)
  2. SharedWorker (less common)

What problems does this solve?

  • Prevents desynchronized session vulnerabilities, such as a user logging out of a banking portal in Tab A but actively interacting with authenticated data in Tab B.
  • Drastically reduces redundant, expensive network payloads by allowing a primary tab to fetch data once and instantly broadcast the parsed payload to sibling tabs.
  • Creates magical, seamless user experiences where cart additions or theme toggles instantly ripple across multiple monitor setups without ever requiring a manual browser refresh.

Data Fetching & APIs

11

How do you design a data fetching layer?

Key concerns:

  • Caching strategy
  • Loading/error states
  • Retry logic
  • Request deduplication
  • Pagination
  • Polling/real-time updates

What problems does this solve?

  • Centralizes complex, repetitive network logic (like injecting JWT authorization headers, intercepting 401s, and formatting deep query parameters) into a single pristine layer.
  • Provides specialized architectural seams explicitly engineered for aggressive caching, identical request deduplication, and intelligent network retry algorithms.
  • Completely abstracts the underlying hardware network implementation (Axios, Fetch, GraphQL) away from the fragile UI components, heavily simplifying unit test mocking.
12

How do you implement infinite scroll?

Using Intersection Observer:

Considerations: Virtualization for large lists, scroll restoration.

What problems does this solve?

  • Prevents browser memory exhaustion and severe DOM lag when rendering thousands of search results or deeply saturated social media feeds.
  • Drastically accelerates initial page load times by intentionally refusing to fetch or render heavy payload data that currently sits outside of the user's active viewport.
  • Replaces clunky, conversion-killing manual pagination buttons with fluid, highly engaging, continuous content consumption loops that maximize user retention.
13

How do you handle real-time updates?

MethodUse CaseProsCons
PollingSimple, low frequencyEasy implementationWasteful, delayed
Long PollingModerate frequencyLess wastefulComplex server-side
WebSocketsHigh frequency, bidirectionalReal-time, efficientConnection management
Server-Sent EventsServer → Client onlySimple, auto-reconnectOne direction

What problems does this solve?

  • Solves the latency limitations of traditional HTTP polling by opening persistent, bi-directional WebSocket connections for instantaneous messaging, trading, or streaming data.
  • Radically decreases massive server load and database strain by completely eliminating thousands of empty, redundant client-side "Are there updates yet?" HTTP requests.
  • Enables wildly engaging modern features like live collaborative editing, active typing indicators, and immediate notification pushing without manual user refreshes.
14

How do you design an offline-first application?

Architecture:

Key components:

  • Local database (IndexedDB)
  • Service Worker for caching
  • Sync queue for offline mutations
  • Conflict resolution strategy

What problems does this solve?

  • Protects crucial user data integrity by intelligently queueing complex outgoing mutations locally while trains go through tunnels or cellular networks completely drop out.
  • Creates ultra-resilient "installable" Progressive Web Apps (PWAs) that successfully launch and render instantly from an airplane via robust Service Worker caching layers.
  • Flawlessly masks spotty, degraded 3G network conditions by explicitly allowing users to deeply read payloads and queue actions against a local IndexedDB replica.
15

What is GraphQL and when would you use it?

A query language where clients request exactly the data they need.

Pros: No over/under-fetching, strong typing, single endpoint. Cons: Complexity, caching harder than REST, learning curve.

Use when: Complex data requirements, mobile apps, multiple clients with different needs.

What problems does this solve?

  • Eradicates the dual massive performance bottlenecks of "over-fetching" (downloading giant payloads for tiny views) and "under-fetching" (requiring complex waterfall REST requests).
  • Provides a self-documenting, strongly-typed schema contract between frontend and backend teams, wildly accelerating parallel development and eradicating endpoint confusion.
  • Allows frontend interfaces to cleanly ask for deeply nested relational data arrays in a single network round-trip, significantly optimizing highly constrained mobile parsing speeds.

Performance & Optimization

16

How do you optimize a slow-loading web application?

Checklist:

  1. Measure first (Lighthouse, Web Vitals, profiling)
  2. Reduce bundle size
    • Code splitting
    • Tree shaking
    • Lazy loading routes/components
  3. Optimize assets
    • Compress images (WebP/AVIF)
    • Lazy load images
    • Use CDN
  4. Improve loading
    • Preload critical resources
    • Defer non-critical JS
    • Inline critical CSS
  5. Cache effectively
    • Service Worker
    • HTTP caching headers
  6. Reduce runtime work
    • Virtualize long lists
    • Debounce/throttle events
    • Memoization

What problems does this solve?

  • Identifies and eliminates catastrophic rendering bottlenecks that cause devastating layout shifts (CLS), sluggish responsiveness (FID), and massively inflated bounce rates.
  • Protects battery life and processing cycles on low-end, constrained mobile devices by intentionally throttling aggressive animations and aggressively memoizing complex calculations.
  • Directly accelerates core business conversion metrics; Amazon mathematically proved that every 100ms of loading latency definitively cost them 1% in raw global revenue.
17

How do you implement code splitting?

Route-level splitting:

Component-level splitting:

What problems does this solve?

  • Shreds massive, monolithic JavaScript bundles into tiny, highly optimized asynchronous chunks that independently load only exactly when the user navigates directly to them.
  • Drastically accelerates the Time To Interactive (TTI) metric by ensuring that massive dependencies (like Markdown parsers or PDF generators) do not block initial core rendering.
  • Protects highly valuable end-user mobile data limits from being wasted on downloading complex administrative dashboards that the standard user will strictly never open.
18

How do you virtualize a large list?

Only render visible items + buffer:

Libraries: react-virtual, react-window, vue-virtual-scroller.

What problems does this solve?

  • Saves browsers from catastrophic crashing by dynamically mathematically calculating and rendering only the 20 DOM nodes actively visible in the window, even if the dataset has 100,000 items.
  • Eradicates heavy garbage collection staggering by transparently recycling off-screen DOM wrappers rather than aggressively allocating and destroying thousands of unique memory nodes.
  • Maintains perfectly smooth 60fps scrolling performance inside incredibly dense data environments like sprawling administrative tables, massive calendars, or infinite social feeds.
19

How do you implement caching on the frontend?

Layers of caching:

LayerMechanismUse Case
MemoryIn-memory storeSession data, computed values
React Query/SWRStale-while-revalidateAPI responses
Browser CacheCache-Control headersStatic assets
Service WorkerCache APIOffline, performance
IndexedDBPersistent storageLarge datasets, offline
localStorageKey-valueSmall, simple data

What problems does this solve?

  • Reduces expensive cloud infrastructure bandwidth bills by aggressively intercepting redundant client network requests directly at the heavily optimized Service Worker intercept layer.
  • Creates an illusion of near-zero latency by perfectly serving heavy contextual data arrays (like product catalog lists) instantly from local memory on rapid subsequent user visits.
  • Provides incredibly fine-grained cache invalidation controls, ensuring that users see instantly updated banking ledgers while gracefully serving slightly stale marketing copy.
20

How do you handle image optimization at scale?

Strategy:

  1. Responsive images
  1. Use an image CDN (Cloudinary, imgix, Cloudflare Images)
    • On-the-fly resizing
    • Format conversion (WebP/AVIF)
    • Quality optimization
  2. Lazy loading for below-fold images
  3. Placeholders (blur-up, LQIP, skeleton)

What problems does this solve?

  • Completely eradicates the number one culprit of massive initial payload bloat, strictly ensuring that highly unoptimized 4K JPEGs do not block the critical rendering path.
  • Automates dynamic art direction by serving next-generation WebP payloads tailored perfectly to the specific DPI, screen size, and viewport orientation of the requesting device.
  • Prevents jarring Cumulative Layout Shifts (CLS) by explicitly reserving space using precise heavily blurred placeholders while asynchronous images lazy-load seamlessly into view.

UI Patterns & Components

21

How do you design a Design System?

Layers:

Key practices:

  • Version and publish as npm package
  • Automated visual regression tests
  • Clear contribution guidelines

What problems does this solve?

  • Ensures absolute pixel-perfect brand consistency across dozens of fragmented applications by enforcing strict, centralized design tokens for colors, typography, and precise spacing.
  • Massively accelerates global engineering velocity by providing developers with pre-vetted, highly accessible, securely tested components rather than rebuilding complex buttons from scratch.
  • Bridges the crippling communication gap between designers and developers by strictly aligning Figma libraries directly with versioned React component NPM packages 1:1.
22

How do you implement a Modal/Dialog system?

Considerations:

  • Portal rendering (outside parent DOM)
  • Focus management (trap focus, restore on close)
  • Accessibility (role="dialog", aria-modal)
  • Scroll locking
  • Stacking multiple modals
  • Keyboard handling (Escape to close)

What problems does this solve?

  • Manages the notorious complexity of infinite z-index stacking context wars by securely mounting dialogue layers explicitly at the root of the DOM via robust React Portals.
  • Protects users with disabilities by strictly trapping keyboard focus cycles exclusively inside the active modal and deliberately hiding the vast background DOM from screen readers.
  • Enforces declarative API constraints that completely prevent multiple conflicting overlapping modals from spawning simultaneously in complex asynchronous data flows.
23

How do you implement a Form with validation?

Architecture:

Key features:

  • Schema-based validation (Zod, Yup)
  • Field-level and form-level errors
  • Async validation (e.g., check username availability)
  • Dirty/touched state tracking

What problems does this solve?

  • Intercepts glaring user input errors instantly before they are ever transmitted, saving expensive server validation cycles and eliminating frustrating network latency delays for the user.
  • Protects backend databases from dangerous edge-case corruption by tightly restricting maximum lengths, explicitly parsing precise formats, and enforcing strict regex structural patterns.
  • Provides highly contextual, instantly actionable localization feedback exactly at the field level, deeply increasing successful data submission rates and vastly improving conversion funnels.
24

How do you implement a Notification/Toast system?

Architecture:

Features:

  • Auto-dismiss with timer
  • User dismissible
  • Queue management (max visible)
  • Position options (top-right, bottom-center, etc.)
  • Animation (enter/exit)

What problems does this solve?

  • Provides beautifully non-blocking, heavily transient feedback for complex asynchronous background operations (like "File Uploaded") without completely derailing the user's active workflow.
  • Orchestrates sophisticated queuing systems that elegantly stack, prioritize, and gracefully auto-dismiss massive bursts of notifications to strictly prevent screen hijacking and visual clutter.
  • Enforces globally consistent placement and fluid entry/exit physics across the entire application ecosystem, communicating critical system health without requiring explicit user interaction.
25

How do you implement an Autocomplete/Typeahead?

Considerations:

  • Debounced input (avoid over-fetching)
  • Keyboard navigation (up/down/enter/escape)
  • Accessibility (combobox role, aria-expanded, aria-activedescendant)
  • Highlight matching text
  • Loading state
  • Empty/no results state
  • Recent searches

What problems does this solve?

  • Prevents massive database DDOS attacks from rapid keystrokes by intelligently utilizing sophisticated debouncing and throttling algorithms algorithms perfectly tuned to human typing cadence.
  • Vastly optimizes user search traversal experiences by gracefully handling completely misspelled queries via fuzzy matching algorithms heavily weighted by localized relevance and caching.
  • Gracefully manages highly complex asynchronous network race conditions to strictly ensure that stale results from a slow 't' query do not wildly overwrite the fast results from an 'te' query.

Security & Auth

26

How do you implement authentication on the frontend?

Token-based auth flow:

Storage options:

StorageXSS SafeCSRF SafePersistence
httpOnly Cookie❌ (needs CSRF token)Yes
localStorageYes
Memory (variable)No (lost on refresh)

Best practice: httpOnly cookie for refresh token, memory for access token.

What problems does this solve?

  • Strictly protects highly sensitive user account pipelines via robust JWT handling, enforcing HttpOnly secure cookie flags that effectively neutralize malicious local XSS extraction attempts.
  • Surgically abstracts the volatile complexity of multi-factor flows, OAuth token refreshing logic, and SSO handshakes away from delicate frontend product UI logic completely.
  • Maintains secure, predictable global session state explicitly across dozens of isolated micro-frontends securely without ever requiring hard browser re-authentications.
27

How do you prevent XSS attacks?

Strategies:

  1. Never use innerHTML with user input
  1. Use framework's auto-escaping (React, Vue escape by default)
  2. Sanitize rich text (DOMPurify for HTML editors)
  3. Content Security Policy (CSP) headers
  1. Avoid eval() and inline scripts

What problems does this solve?

  • Defends against devastating malicious script injections by tightly enforcing precise Content Security Policies (CSP) and deeply sanitizing absolutely all untrusted user-generated markdown inputs.
  • Protects crucial user session tokens by strictly refusing to ever store highly sensitive authentication payloads openly inside easily compromised localStorage or raw JavaScript variables.
  • Utilizes explicit DOM-purification libraries to carefully strip out dangerous `eval()` calls and severely dangerous remote `<iframe>` embeddings safely before browser rendering.
28

How do you implement role-based access control (RBAC)?

Architecture:

Important: Always enforce permissions on the backend too!

What problems does this solve?

  • Explicitly restricts unauthorized administrative system mutations entirely at the router boundary by fundamentally completely blocking the rendering of components tied to restricted scopes.
  • Dramatically simplifies complex organizational logic by securely binding nested group permissions entirely to centralized, highly verifiable backend authorization matrixes.
  • Optimizes initial frontend delivery payloads severely by deliberately refusing to deliver large chunks of administrative dashboard JavaScript code entirely to unprivileged standard users.

Advanced Topics

29

How do you handle errors gracefully?

Strategy:

  1. Error Boundaries (catch React rendering errors)
  1. API error handling
  1. Graceful degradation (show partial UI if some data fails)

What problems does this solve?

  • Prevents total catastrophic "white screen of death" failures by surrounding isolated component sub-trees with resilient React Error Boundaries that gracefully trap fatal exceptions.
  • Captures massive amounts of highly specific stack-trace data telemetry behind the scenes tightly integrated with platforms like Sentry, radically accelerating debugging timelines for specific crashes.
  • Intelligently translates incredibly cryptic failed server status codes into highly actionable, beautiful local UI recovery states that actively help the specific user immediately try again.
30

How do you approach logging and monitoring on the frontend?

Components:

  1. Error tracking (Sentry, Bugsnag)
  1. Analytics/Events (Mixpanel, Amplitude, GA)
  1. Performance monitoring (Core Web Vitals)
  1. Session replay (FullStory, LogRocket)

Privacy: Be mindful of PII, respect Do Not Track.

What problems does this solve?

  • Surfaces completely invisible structural anomalies quickly by securely aggressively tracking unique frontend metrics explicitly like "Time to Interactive" against global geographical baselines.
  • Creates detailed breadcrumb logs of exactly what components the specific user clicked gracefully moments before a fatal unhandled promise rejection aggressively triggered an error boundary.
  • Provides deep, statistical insight into true conversion funnel drop-offs exactly, decisively allowing product leaders securely to prioritize optimizations gracefully based upon actual heavy usage.