Frontend Development Interview Questions for 10 Years Experience
40 questions with answers for candidates with 10+ years of experience — 14 medium, 26 hard.
What interviewers expect: 10 years experience
At ten years, roles include principal engineer, frontend architect or engineering manager. Interviews centre on organisation-wide technical vision, build-versus-buy decisions, hiring and growing frontend talent, accessibility and compliance at scale, and aligning frontend investments with business outcomes. Hands-on depth is still checked through architecture deep dives.
This set is weighted towards Frontend Architecture (9), Browser APIs (6), Build Tools and Tooling (6), Web Performance (5).
Technical vision Organisation-wide architecture Talent development Business alignment
Solved at this levelStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
✓ 3 questions free • Unlock the rest in seconds
01
In a single-page app, the back button takes users out of the site instead of to the previous filter. Why?
The app changes the view without adding history entries, so the browser has nothing to go back to within the site. Each meaningful navigation, like changing a category or opening a product, should call pushState or the router's navigate function, while minor changes such as typing in search can use replaceState. The app must also listen to popstate and restore the view and scroll position from the URL.
02
When a user logs out in one tab, other open tabs stay logged in. How do you fix it?
I would broadcast a logout message using BroadcastChannel, or the storage event as a fallback, so every tab clears its in-memory state and redirects to the login page. The server must also invalidate the session or refresh token, so stale tabs fail their next API call with a 401, which the app handles by logging out. Both client sync and server invalidation are needed.
03
How would you choose a frontend framework for a new project?
I would base it on project needs and team context rather than trends: team experience, hiring market in India, SEO and rendering requirements, ecosystem maturity, long-term support and performance on target devices. React has the largest ecosystem and talent pool, Angular suits large enterprise teams wanting an opinionated structure, Vue is approachable, and Svelte or Astro produce less JavaScript. A small proof of concept helps confirm the choice.
04
How do you estimate the time needed for a frontend feature?
I break the feature into small parts: components, states such as loading, empty and error, API integration, responsive behaviour, accessibility and tests. I estimate each part, add time for reviews and unknowns, and flag dependencies like pending designs or APIs. For example, a filter panel I estimated at five days was delivered in five because I had listed edge cases upfront instead of discovering them late.
05
Production builds take eight minutes on an old webpack setup. How would you speed them up?
I would profile the build to find slow loaders and plugins. Quick wins include replacing Babel and Terser with SWC or esbuild, enabling persistent filesystem caching, and removing unused plugins. For a bigger gain, I would evaluate migrating to Vite or Rspack, which keeps webpack-compatible config. In CI, caching dependencies and build outputs and running only affected packages in a monorepo cut time further.
06
What is the same-origin policy and how does postMessage work around it?
An origin is the combination of scheme, host and port. The same-origin policy stops scripts from reading data or DOM of another origin, such as an embedded iframe from a payment provider. window.postMessage lets two windows or iframes exchange messages safely across origins. The receiver must check event.origin against an allow-list, and the sender should specify the exact target origin instead of '*'.
07
How do you secure a modern frontend application beyond what the framework provides?
Frameworks escape output by default, but risks remain: dangerouslySetInnerHTML or v-html with unsanitised data, javascript: URLs in links, and vulnerable npm packages. I would sanitise any HTML with DOMPurify, enforce a strict Content Security Policy with nonces, use Subresource Integrity for CDN scripts, keep tokens in HttpOnly cookies, run dependency audits in CI and never place secrets in frontend environment variables.
08
Ten teams work on one large frontend and releases keep blocking each other. What would you propose?
I would first try a modular monorepo with clear package boundaries, code owners, affected-only CI with Nx or Turborepo, and trunk-based development with feature flags, which removes most blocking at low cost. If teams truly need independent deployments, I would introduce micro-frontends along business domains, such as search, product and checkout, with a shared design system and strict performance budgets to control duplication.
09
Which rendering strategy would you choose for a large e-commerce site?
I would mix strategies by page type. Category and product pages need SEO and fast LCP, so I would use static generation with incremental revalidation or server rendering with CDN caching. Cart, checkout and account pages are personalised, so server rendering without shared caching or client rendering works. Prices and stock can be fetched fresh on the client. Frameworks like Next.js, Nuxt and Astro support this per-route choice.
10
Collect Core Web Vitals from real users with the web-vitals library.
Report metrics to your analytics endpoint:
import { onLCP, onINP, onCLS } from 'web-vitals';
function send(metric) {
const body = JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating,
page: location.pathname
});
navigator.sendBeacon('/analytics/vitals', body);
}
onLCP(send);
onINP(send);
onCLS(send);
sendBeacon delivers data reliably even when the page is closing. Aggregate at the 75th percentile per page.
11
An accordion animation stutters on low-end Android phones. What is wrong?
Most likely it animates height, max-height or margin, which forces layout recalculation every frame. I would check the Performance panel for long layout events. Fixes include animating transform and opacity, using the newer interpolate-size or calc-size features for height where supported, or animating grid-template-rows from 0fr to 1fr, which is cheaper. Testing with CPU throttling in DevTools reveals these issues before users do.
12
How would you migrate a large JavaScript codebase to TypeScript?
I would migrate gradually rather than in one big rewrite. First add tsconfig with allowJs and checkJs off, rename entry files to .ts, and keep the build working. Then convert shared utilities and API types first, because many files depend on them, and enable strict for new files. I would track the number of any usages, add type checking to CI, and convert feature folders as they are touched.
13
End-to-end tests fail randomly in CI about one run in five. How do you stabilise them?
I would collect traces, videos and screenshots of failures to see what actually happened. Usual fixes are replacing fixed waits with auto-waiting assertions, waiting for specific network responses, seeding isolated test data per test, mocking unstable third-party services, and disabling animations. I would quarantine persistently flaky tests with a tracking ticket rather than letting the team ignore red builds, and retry only as a temporary measure.
14
The bundle analyser shows two copies of the same library. How do you fix it?
Duplicates happen when different packages depend on incompatible versions, so the package manager installs both. I would run npm ls library-name or pnpm why to see who requires which version, then update dependents to a common version, use overrides or resolutions to force one compatible version, or configure resolve.dedupe in Vite. Duplicate framework copies are especially harmful because they can break shared state and context.
A Proxy wraps an object and intercepts operations like get, set, has and deleteProperty through handler traps. Reflect provides matching methods that perform the default behaviour, so traps can add logic and then call Reflect.set. Reactive frameworks such as Vue 3 use Proxies to track which properties a component reads and re-render when they change. Proxies add overhead, so they suit framework internals more than hot loops.
16
How do monorepo tools like Turborepo or Nx help frontend teams?
A monorepo holds multiple apps and shared packages, such as a design system and utilities, in one repository using package manager workspaces. Turborepo and Nx add a task graph that understands dependencies between packages, run builds and tests only for affected packages, and cache outputs locally and remotely. This keeps CI fast as the repo grows and makes cross-package changes atomic in one pull request.
17
Build an API client that refreshes an expired access token once and retries.
Situation: a senior engineer rejected my pull request for a new dashboard because the CSS was hard to maintain. Task: I had to rework it without missing the sprint. Action: I asked for a short call to understand the concerns, refactored styles into reusable components with tokens, and added notes explaining my choices. Result: the PR was approved, and the components were later reused in two other screens.
19
Run linting and formatting automatically before each commit.
Use Husky with lint-staged:
npm i -D husky lint-staged
npx husky init
echo 'npx lint-staged' > .husky/pre-commit
// package.json
"lint-staged": {
"*.{ts,tsx,js}": ["eslint --fix", "prettier --write"],
"*.{css,md,json}": "prettier --write"
}
Only staged files are checked, so commits stay fast. CI should still run the full lint because hooks can be skipped locally.
20
Write a DeepReadonly type using mapped and conditional types.
TypeScript compares types by their shape, not by their declared names. If an object has all the properties a type requires, it is compatible, even if it was never declared as that type. This is flexible but can let a UserId string be passed where an OrderId string is expected. Teams use branded types, such as string & { __brand: 'UserId' }, to simulate nominal typing for important identifiers.
22
What is the difference between :is() and :where()?
Both take a list of selectors and match any of them, reducing repetition, for example :is(h1, h2, h3) a. The difference is specificity: :is() takes the specificity of its most specific argument, while :where() always has zero specificity. That makes :where() perfect for resets and library defaults that users should easily override, while :is() keeps normal priority.
23
An audit finds twenty performance issues. How do you decide what to fix first?
Situation: a Lighthouse and field data audit of our app listed many issues. Task: I had one sprint to show improvement. Action: I ranked issues by user impact and effort, focusing first on the LCP image, render-blocking CSS and one oversized library on the most visited pages. Result: these three fixes delivered most of the gain, and I scheduled the remaining smaller items into later sprints.
24
TypeScript types say a field exists, but the app crashes because the API did not send it. How do you prevent this?
TypeScript only checks at compile time; it cannot guarantee what a server returns at runtime. I would validate responses at the boundary with a schema library like Zod or Valibot, deriving TypeScript types from the schema so they never drift. Invalid data then fails clearly with a logged error and a fallback UI. Generating types from OpenAPI specs also keeps frontend and backend contracts aligned.
25
Field data shows poor INP on the product page's Add to Cart button. How do you investigate?
I would reproduce with CPU throttling in the Performance panel and record the click to see what runs. Typical findings are a heavy handler, analytics calls running synchronously, or a large re-render of the whole page. Fixes include updating the button state immediately, deferring non-urgent work like tracking with scheduler.yield or requestIdleCallback, and narrowing which components re-render. Attribution data from web-vitals helps find the exact element and script.
26
Write a Playwright end-to-end test for a login flow.
Use role-based locators and web-first assertions:
import { test, expect } from '@playwright/test';
test('user can log in and see dashboard', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('student@example.com');
await page.getByLabel('Password').fill('Secret@123');
await page.getByRole('button', { name: 'Log in' }).click();
await expect(page).toHaveURL(/dashboard/);
await expect(page.getByRole('heading', { name: 'My courses' })).toBeVisible();
});
Assertions auto-wait, so no manual sleeps are needed. Save login state with storageState to reuse in other tests.
27
Test a DOM form with Testing Library and user-event.
Simulate real typing and clicks:
import { screen } from '@testing-library/dom';
import userEvent from '@testing-library/user-event';
import { mountSignupForm } from './signup';
it('shows an error for an invalid mobile number', async () => {
document.body.innerHTML = '<div id=app></div>';
mountSignupForm(document.getElementById('app'));
const user = userEvent.setup();
await user.type(screen.getByLabelText('Mobile'), '12345');
await user.click(screen.getByRole('button', { name: 'Sign up' }));
expect(screen.getByRole('alert')).toHaveTextContent('Enter a valid mobile number');
});
toHaveTextContent comes from @testing-library/jest-dom.
Cache-first serves from cache and falls back to network, ideal for versioned static assets. Network-first tries the network and falls back to cache, suited to HTML and API data that should be fresh. Stale-while-revalidate returns the cached copy immediately while fetching an update in the background, good for avatars or non-critical data. Libraries like Workbox implement these strategies and handle cache expiry and versioning.
Flaky tests pass and fail without code changes. Common causes are fixed sleeps instead of waiting for conditions, race conditions with network responses, shared state between tests, reliance on real time or random data, animations, and test order dependencies. Unstable selectors and real third-party services also contribute. Fixes include auto-waiting assertions, isolated test data, mocked clocks, and running tests in parallel to expose hidden shared state.
30
Split vendor libraries into separate chunks and visualise the bundle.
Use manualChunks and a visualiser plugin:
import { defineConfig } from 'vite';
import { visualizer } from 'rollup-plugin-visualizer';
export default defineConfig({
plugins: [visualizer({ filename: 'stats.html', gzipSize: true })],
build: {
rollupOptions: {
output: {
manualChunks: { charts: ['chart.js'], editor: ['@tiptap/core'] }
}
}
}
});
After building, open stats.html to see which modules take the most space and decide what to lazy load or replace.
31
Field agents need a form app that works in areas with no internet. How would you build it?
I would build an offline-first PWA: a service worker caches the app shell, and submissions are saved in IndexedDB with a sync status. When connectivity returns, a background sync or online event uploads pending records with idempotency keys so retries never create duplicates. The UI clearly shows synced and pending items. Conflict rules, such as server timestamps winning, must be agreed with the backend team.
I would debounce input by about 200 milliseconds, cancel outdated requests with AbortController and cache recent queries in a Map. Suggestions render in an accessible combobox pattern with aria-expanded, aria-activedescendant and arrow key navigation. I would highlight matched text safely, show loading and empty states, and limit results to around eight. Measuring latency and prefetching popular terms keep it feeling instant on slow networks.
34
How did you convince stakeholders to prioritise performance work over new features?
Situation: our product team kept postponing performance fixes for new features. Task: I needed to show the business value. Action: I correlated our real user data with conversion and found that sessions with LCP above 4 seconds converted at about half the rate. I proposed a two-sprint plan with clear targets. Result: leadership approved it, LCP improved by 40 percent and checkout conversion rose measurably.
35
What are micro-frontends and when do they make sense?
Micro-frontends split a large web app into independently developed and deployed pieces, each owned by a team, composed at runtime with Module Federation, web components or server-side composition. They help large organisations where many teams block each other on one release. The costs are duplicated dependencies, inconsistent UX, complex shared state and harder performance tuning. For most teams, a well-structured monorepo is simpler.
36
Several teams contribute CSS to one large app and styles keep breaking each other. What do you propose?
I would introduce scoping so styles cannot leak, using CSS Modules or a consistent naming convention per team, and organise global styles with cascade layers for reset, tokens, components and utilities. A shared design token set and component library reduces one-off styles. Linting with Stylelint, visual regression tests in CI and clear ownership of global files prevent new conflicts.
37
Which tsconfig options are important for a strict codebase?
strict: true enables a family of checks, including strictNullChecks and noImplicitAny, and should be on for new projects. noUncheckedIndexedAccess adds undefined to array and record lookups, catching many runtime errors. exactOptionalPropertyTypes, noImplicitOverride and noFallthroughCasesInSwitch add more safety. For bundler-based apps, moduleResolution: bundler, isolatedModules and verbatimModuleSyntax keep TypeScript aligned with how tools like Vite compile code.
38
Your page embeds a payment iframe from another domain and needs its result. How do you do it safely?
The iframe should send the result with parent.postMessage(data, 'https://yourshop.com'), and the page listens for message events, checking event.origin against the exact payment domain and validating the data shape before acting. The frontend message should only update UI; the final payment status must be confirmed from your server through the gateway's webhook or verification API, since messages can be spoofed.
39
Lighthouse shows a score of 95, but Search Console reports failing Core Web Vitals. Why?
Lighthouse is a single lab run on a simulated device, while Search Console uses field data from real Chrome users at the 75th percentile over 28 days. Real users may have slower phones, interact with the page, which affects INP and CLS later in the session, or see different content like ads and personalised blocks. I would add real user monitoring with attribution to find which pages and elements fail.
40
After a deployment, some users keep seeing the old version of your PWA. Why?
The old service worker is still controlling the page and serving cached files; a new worker waits until all tabs using the old one are closed. I would version the cache, delete old caches in the activate event, and show an 'Update available' prompt that calls skipWaiting and reloads. The sw.js file itself must be served with no-cache headers so browsers check for updates promptly.
Frequently asked questions
What is asked in Frontend Development interviews for 10+ years of experience?
At ten years, roles include principal engineer, frontend architect or engineering manager. Interviews centre on organisation-wide technical vision, build-versus-buy decisions, hiring and growing frontend talent, accessibility and compliance at scale, and aligning frontend investments with business outcomes. Hands-on depth is still checked through architecture deep dives.
How many questions should I practise before a Frontend Development interview?
Work through all 40 questions here, then the company-wise sets for the employers you are targeting. Quality matters more than count: be able to explain why each answer is right.
Which topics matter most for 10+ years of experience?
Focus first on Technical vision, Organisation-wide architecture, Talent development, Business alignment.