Skip to content

BrowserStack Frontend Development Interview Questions & Answers

Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.

About BrowserStack hiring for Frontend Development roles

BrowserStack is a cloud-based software testing platform that lets teams test websites and mobile apps on real browsers and devices. Its products include Live, Automate, App Automate, Percy and Test Observability. It hires for software engineers, SDETs, support engineers and data analysts, many working on test infrastructure at scale.

For Frontend Development roles, this BrowserStack practice set focuses most on CSS Architecture and Accessibility (7), TypeScript (5), Build Tools and Tooling (4), Frontend Architecture (3). It has 1 easy, 18 medium, 11 hard questions, so you can start easy and work up to the harder ones.

Company type
Product
Headquarters
Mumbai, India
Main India offices
Mumbai, Bengaluru

BrowserStack Frontend Development interview process

  1. Online coding assessment
  2. Technical round 1 (DSA or coding)
  3. Technical round 2 (design or debugging)
  4. Hiring manager round
  5. HR round

Typical pattern based on public candidate experiences. Rounds vary by role, team and year.

Solved for BrowserStackStart 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

Create a type where all fields are optional except id.

Save to ▾
Show answer
Combine Pick and Partial with an intersection: interface Product { id: string; name: string; price: number; stock: number; } type ProductUpdate = Pick<Product, 'id'> & Partial<Omit<Product, 'id'>>; const update: ProductUpdate = { id: 'p1', price: 799 }; // const bad: ProductUpdate = { price: 799 }; // error: id missing This is a common pattern for PATCH request payloads, ensuring the identifier is always present.
02

State is passed through many component layers and global state has become chaotic. How do you restructure it?

Save to ▾
Show answer
I would first classify state: server data moves to a data-fetching cache like TanStack Query, URL-worthy state such as filters moves to query parameters, and truly local state moves back into components. What remains global, like user session and theme, goes into a small, well-defined store or context split by concern. Composition patterns, passing components as children, also remove much prop drilling.
03

Set up ESLint with the flat config for a TypeScript project.

Save to ▾
Show answer
Install packages and create eslint.config.js: // npm i -D eslint @eslint/js typescript-eslint import js from '@eslint/js'; import tseslint from 'typescript-eslint'; export default tseslint.config( js.configs.recommended, ...tseslint.configs.recommended, { rules: { '@typescript-eslint/no-explicit-any': 'warn', 'no-console': ['warn', { allow: ['error'] }] } }, { ignores: ['dist/'] } ); Run npx eslint . locally and in CI. Leave formatting to Prettier so the two tools do not conflict.
04

In a single-page app, the back button takes users out of the site instead of to the previous filter. Why?

Save to ▾
Show answer
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.
05

What is the difference between :is() and :where()?

Save to ▾
Show answer
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.
06

Users report errors you cannot reproduce. How do you set up frontend observability?

Save to ▾
Show answer
I would add an error monitoring tool like Sentry with uploaded source maps, release tags and user context such as browser and route, without personal data. Real user monitoring tracks Web Vitals and slow API calls. Breadcrumbs of clicks and network requests before an error help reproduce issues, and session replay with privacy masking shows what users saw. Alerts on error spikes after a release enable quick rollbacks.
07

Write a type-safe getProperty function using generics and keyof.

Save to ▾
Show answer
Constrain the key to the object's own keys: function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const course = { title: 'Frontend', weeks: 14 }; const weeks = getProperty(course, 'weeks'); // number // getProperty(course, 'price'); // compile error T[K] is an indexed access type, so the return type matches the chosen property. Typos in key names are caught at compile time.
08

A full-screen hero section is cut off at the bottom on mobile phones. How do you fix it?

Save to ▾
Show answer
The section uses height: 100vh, which on mobile includes the area hidden behind the browser's address bar. I would change it to min-height: 100svh or 100dvh so the height matches the visible viewport, keeping 100vh as a fallback line before it for very old browsers. Using min-height instead of height also lets content grow on small screens instead of overflowing.
09

The frontend test suite takes 20 minutes in CI. How do you make it faster?

Save to ▾
Show answer
I would measure which tests are slowest. Options include running tests in parallel and sharding across CI machines, moving logic checks from end-to-end tests into faster integration tests, reusing logged-in state instead of logging in every time, and running only tests affected by changed files on pull requests with the full suite nightly. Replacing real network calls with MSW and caching dependencies also helps.
10

The bundle analyser shows two copies of the same library. How do you fix it?

Save to ▾
Show answer
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.
11

Animate a modal smoothly when it opens without causing layout work.

Save to ▾
Show answer
Animate only transform and opacity, which run on the compositor: .modal { opacity: 0; transform: translateY(16px) scale(0.98); transition: opacity 200ms ease, transform 200ms ease; } .modal.is-open { opacity: 1; transform: none; } @media (prefers-reduced-motion: reduce) { .modal { transition: opacity 100ms linear; transform: none; } } Animating top, height or margin instead would trigger layout on every frame and cause jank on low-end phones.
12

Write a fetch wrapper that retries with exponential backoff.

Save to ▾
Show answer
Retry on network errors and 5xx responses, doubling the delay each time: async function fetchWithRetry(url, options = {}, retries = 3, delay = 500) { try { const res = await fetch(url, options); if (res.status >= 500 && retries > 0) throw new Error('Server ' + res.status); return res; } catch (err) { if (retries === 0) throw err; await new Promise(r => setTimeout(r, delay)); return fetchWithRetry(url, options, retries - 1, delay * 2); } } Do not retry 4xx errors, and only retry idempotent requests.
13

Write a DeepReadonly type using mapped and conditional types.

Save to ▾
Show answer
Recursively mark nested properties readonly: type DeepReadonly<T> = T extends (...args: any[]) => any ? T : T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T; interface Config { api: { baseUrl: string; retries: number } } const config: DeepReadonly<Config> = { api: { baseUrl: '/api', retries: 3 } }; // config.api.retries = 5; // error Functions are left untouched, and primitives end the recursion.
14

What are CSS logical properties?

Save to ▾
Show answer
Logical properties describe layout relative to the writing direction instead of physical sides. margin-inline-start means left in English but right in Arabic or Urdu, and padding-block maps to top and bottom in horizontal text. Using them, with the dir attribute on html, lets one stylesheet support both left-to-right and right-to-left languages without overrides. Sizes like inline-size replace width in the same way.
15

An accordion animation stutters on low-end Android phones. What is wrong?

Save to ▾
Show answer
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.
16

Your page embeds a payment iframe from another domain and needs its result. How do you do it safely?

Save to ▾
Show answer
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.
17

Run linting and formatting automatically before each commit.

Save to ▾
Show answer
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.
18

Users in India see order dates shifted by a day. What is the likely bug?

Save to ▾
Show answer
The server probably sends a date like 2026-11-12 without time zone, and new Date('2026-11-12') treats date-only strings as UTC midnight, while other formats are parsed as local time, causing shifts around midnight. I would send full ISO timestamps with offsets, store times in UTC, and format for display with Intl.DateTimeFormat('en-IN', { timeZone: 'Asia/Kolkata' }). The Temporal API, now arriving in browsers, makes this safer.
19

Add automated accessibility checks to Playwright tests.

Save to ▾
Show answer
Use the axe-core integration: import { test, expect } from '@playwright/test'; import AxeBuilder from '@axe-core/playwright'; test('home page has no serious accessibility violations', async ({ page }) => { await page.goto('/'); const results = await new AxeBuilder({ page }) .withTags(['wcag2a', 'wcag2aa']) .analyze(); const serious = results.violations.filter(v => ['serious', 'critical'].includes(v.impact)); expect(serious).toEqual([]); }); Automated tools catch only part of accessibility issues, so keyboard and screen reader checks are still needed.
20

npm audit reports a critical vulnerability in a dependency. What do you do?

Save to ▾
Show answer
I would check whether the vulnerable package is actually used in the production bundle or only in build tooling, and whether the vulnerable code path is reachable. Then I would update to a patched version, using npm update or overrides for transitive dependencies. If no fix exists, I would look for an alternative package or mitigate. Automated tools like Dependabot or Renovate keep dependencies current.
21

What are tagged template literals?

Save to ▾
Show answer
A tagged template is a function placed before a template literal, like html`<p>${name}</p>`. The function receives the static string parts as an array and the interpolated values separately, so it can escape, transform or validate values before joining them. Libraries use this pattern for safe HTML templating, CSS-in-JS and GraphQL queries. Normal template literals simply interpolate values and support multi-line strings.
22

What are long tasks and why do they hurt user experience?

Save to ▾
Show answer
A long task is any main-thread work lasting more than 50 milliseconds. While it runs, the browser cannot respond to taps or paint updates, so the page feels frozen. Common sources are large script evaluation, heavy JSON processing, big framework re-renders and third-party scripts. The Performance panel highlights them with red corners, and splitting work into smaller chunks or moving it to a worker keeps the page responsive.
23

Type checking takes several minutes in a large monorepo. How do you speed it up?

Save to ▾
Show answer
I would enable project references with composite builds so only changed packages are rechecked, and turn on incremental with build info files cached in CI. skipLibCheck avoids rechecking node_modules declarations. Very complex conditional types and huge unions slow the checker, so I would profile with --generateTrace and simplify hotspots. The bundler can use fast transpilation while type checking runs separately in parallel.
24

How do you test code that depends on the current date or timers?

Save to ▾
Show answer
Real time makes tests slow and nondeterministic. I would use fake timers, such as vi.useFakeTimers() and vi.setSystemTime(new Date('2026-11-12T10:00:00+05:30')), then advance time with vi.advanceTimersByTime to test debounce, countdowns or expiry logic instantly. Restoring real timers after each test avoids leaking state. Designing functions to accept a clock or date parameter makes them even easier to test.
25

How do you handle unclear requirements from a product manager?

Save to ▾
Show answer
Situation: a product manager asked for 'offline support' in our web app without details. Task: I needed clarity before estimating. Action: I listed specific questions, which screens, read-only or editing, how long offline, and shared a quick prototype showing two options with effort estimates. Result: we agreed on read-only offline access for the order history, which shipped in one sprint instead of an open-ended project.
26

Build an API client that refreshes an expired access token once and retries.

Save to ▾
Show answer
Share one refresh promise so parallel requests do not refresh repeatedly: let refreshing = null; async function api(path, options = {}) { let res = await fetch(path, { ...options, credentials: 'include' }); if (res.status !== 401) return res; refreshing ??= fetch('/auth/refresh', { method: 'POST', credentials: 'include' }) .finally(() => (refreshing = null)); const refreshed = await refreshing; if (!refreshed.ok) { location.assign('/login'); throw new Error('Session expired'); } return fetch(path, { ...options, credentials: 'include' }); } Cookies carry the tokens, so JavaScript never reads them.
27

You are asked to build a design system used by several products. How do you approach it?

Save to ▾
Show answer
I would start with an audit of existing UI to find common components and inconsistencies, then define design tokens with the design team. I would build accessible base components like button, input, modal and table, document them in Storybook with usage guidelines, and publish them as a versioned package. Semantic versioning, changelogs and visual regression testing help products upgrade safely.
28

What is hydration and why can it hurt performance?

Save to ▾
Show answer
With server-side rendering, the server sends ready HTML so content appears quickly, but the page is not interactive until the framework downloads JavaScript and hydrates, attaching event listeners and rebuilding state. On slow phones, this causes a gap where buttons look ready but do nothing, hurting INP. Techniques like streaming, partial or progressive hydration, islands architecture and server components reduce how much JavaScript must hydrate.
29

TypeScript types say a field exists, but the app crashes because the API did not send it. How do you prevent this?

Save to ▾
Show answer
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.
30

Your app must now support an Arabic right-to-left version. What changes are needed in CSS?

Save to ▾
Show answer
I would set dir='rtl' on the html element for that locale and replace physical properties like margin-left, padding-right and left with logical ones such as margin-inline-start and inset-inline-start. Flexbox and Grid follow direction automatically. Directional icons like arrows need flipping with a transform in RTL, while logos and media do not. I would test layouts with real Arabic text, which has different line heights.

Tips to crack the BrowserStack Frontend Development interview

  • Learn Selenium, Appium and Playwright basics, since BrowserStack products are built around these testing frameworks.
  • Try a BrowserStack free trial and run an automated test to understand the user experience.
  • Practise debugging and system design questions related to running many parallel tests on real devices.
  • Keep a one-minute story ready for every project on your CV: problem, your part, tools, result.
  • Practise the hard questions on this page aloud; BrowserStack interviewers usually ask follow-ups on your first answer.

Frequently asked questions

How many rounds are there in the BrowserStack Frontend Development interview?

Candidates usually go through 5 stages: Online coding assessment; Technical round 1 (DSA or coding); Technical round 2 (design or debugging); Hiring manager round; HR round. The exact rounds change with the role, team, location and your experience, so confirm the process with the recruiter.

Which topics should I prepare for the BrowserStack Frontend Development interview?

This practice set leans on CSS Architecture and Accessibility (7), TypeScript (5), Build Tools and Tooling (4), Frontend Architecture (3). Revise those first, then practise explaining one or two of your own projects end to end, because most BrowserStack interviewers ask you to walk through real work.

Are these the exact questions asked at BrowserStack?

No. These are curated practice questions that match the skills and difficulty usually tested in product interviews like BrowserStack's. They are not a leaked or verified list of past questions.

Where does BrowserStack hire Frontend Development professionals in India?

BrowserStack has large teams in Mumbai, Bengaluru. Openings and locations change often, so check the BrowserStack careers page and filter by city and experience.

Frontend Development questions for similar companies