Skip to content

Frontend Development Interview Questions in Kolkata

36 practice questions with answers for Frontend Development interviews in Kolkata.

Frontend Development jobs in Kolkata

Kolkata has a steady IT-services and BFSI technology job market around Salt Lake Sector V and New Town. Many openings are with service companies and their delivery centres, with a focus on strong fundamentals.

Below are 36 questions that match the mix of service, product and domain employers hiring frontend developers in Kolkata.

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

Editing one item in a copied list also changes the original list. Why?

Save to ▾
Show answer
Copying an array with spread or slice creates a new array, but the objects inside are still the same references. Changing copy[0].qty changes the original object too. The fix is to create new objects for changed items, for example list.map(item => item.id === id ? { ...item, qty: item.qty + 1 } : item), or use structuredClone when a full deep copy is genuinely needed.
02

How does type narrowing work in TypeScript?

Save to ▾
Show answer
Narrowing is how TypeScript refines a broad type to a specific one inside a code branch. It understands typeof checks, instanceof, the in operator, equality checks, truthiness and discriminant properties. For example, inside if (typeof value === 'string') you can call value.toUpperCase(). Custom type guard functions returning value is User extend this to your own checks, and assertion functions narrow after they run.
03

Marketing has added many third-party scripts and the site has become slow. What do you do?

Save to ▾
Show answer
I would measure each script's cost using the Performance panel and request blocking in DevTools. Then I would remove unused tags, load the rest with async or defer, delay non-essential ones like chat widgets until user interaction or idle time, and use facades, such as a static image for embedded videos. Moving tag management to a server-side setup and agreeing on a script budget with marketing prevents repeat problems.
04

Why does await inside forEach not wait for each item?

Save to ▾
Show answer
forEach ignores the promise returned by an async callback, so all callbacks start almost at once and forEach finishes before any await completes. Code after it runs too early. For sequential processing, use a for...of loop with await inside. For parallel processing with a final result, use await Promise.all(items.map(async item => ...)). Choosing between them depends on whether order and rate limits matter.
05

Test a DOM form with Testing Library and user-event.

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

What is the guiding principle of Testing Library and why query by role?

Save to ▾
Show answer
Testing Library encourages testing the way users interact: find elements by what they see and hear, not by implementation details like class names or component internals. getByRole('button', { name: 'Submit' }) is preferred because it also verifies the element is accessible. Tests written this way survive refactors and catch real accessibility problems. Test ids are a last resort when no accessible query works.
07

Create a typed fetch helper with generics.

Save to ▾
Show answer
Let callers specify the expected response type: async function getJson<T>(url: string): Promise<T> { const res = await fetch(url); if (!res.ok) throw new Error(`Request failed: ${res.status}`); return res.json() as Promise<T>; } interface Course { id: number; title: string; } const courses = await getJson<Course[]>('/api/courses'); courses[0].title.toUpperCase(); The cast trusts the server, so for untrusted data validate with a schema library like Zod before returning.
08

What is the difference between local UI state, global state and server state?

Save to ▾
Show answer
Local state belongs to one component, like whether a dropdown is open. Global client state is shared across the app, like theme or the logged-in user. Server state is data owned by the backend, such as orders, that must be fetched, cached, refreshed and kept in sync. Treating server state separately with tools like TanStack Query removes much of the code teams once wrote in global stores.
09

Detect offline status and retry queued requests when the connection returns.

Save to ▾
Show answer
Listen for online and offline events and keep a small queue: const queue = []; async function send(req) { if (!navigator.onLine) { queue.push(req); showBanner('You are offline'); return; } await fetch(req.url, req.options); } window.addEventListener('online', async () => { hideBanner(); while (queue.length) await send(queue.shift()); }); window.addEventListener('offline', () => showBanner('You are offline')); navigator.onLine can report true on captive networks, so treat failed fetches as offline too. Persist the queue in IndexedDB for reliability.
10

When should you mock in frontend tests, and what is Mock Service Worker?

Save to ▾
Show answer
Mock things that are slow, nondeterministic or outside your control, such as network calls, timers and browser APIs, but avoid mocking your own modules heavily, which makes tests pass while the real integration breaks. Mock Service Worker intercepts requests at the network level in both browser and Node, so your real fetch code runs against defined handlers. The same handlers can power tests, Storybook and local development.
11

Predict the output order of synchronous code, promises and setTimeout.

Save to ▾
Show answer
Synchronous code runs first, then microtasks, then macrotasks: console.log('A'); setTimeout(() => console.log('B'), 0); Promise.resolve().then(() => console.log('C')); queueMicrotask(() => console.log('D')); console.log('E'); // Output: A, E, C, D, B A and E are synchronous. C and D are microtasks queued in order. B is a macrotask and waits until the microtask queue is empty, even with a 0 ms delay.
12

What is the testing pyramid, and how does the testing trophy differ?

Save to ▾
Show answer
The testing pyramid suggests many fast unit tests, fewer integration tests and very few slow end-to-end tests. The testing trophy, popular for frontend work, puts most effort into integration tests that render components with real behaviour, supported by static analysis like TypeScript and ESLint at the base. Both aim for confidence at reasonable cost; the trophy reflects that UI bugs often appear where units connect.
13

Explain any, unknown and never.

Save to ▾
Show answer
any turns off type checking completely, so errors slip through silently. unknown also accepts any value, but you must narrow it with typeof, instanceof or a type guard before using it, which makes it the safe choice for API responses and catch errors. never represents values that never occur, such as a function that always throws, or the leftover case in an exhaustive switch over a union.
14

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.
15

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.
16

A dashboard must show live order updates. Would you use polling, Server-Sent Events or WebSockets?

Save to ▾
Show answer
Polling is simplest and fine if updates every 30 seconds are acceptable. Server-Sent Events push one-way updates from server to browser over HTTP with automatic reconnection, ideal for live orders, notifications and stock tickers. WebSockets provide full two-way communication, needed for chat or collaborative editing, but require more infrastructure. For a one-way dashboard, I would choose SSE and reconnect gracefully on network changes.
17

Most of your users are on low-end Android phones with slow networks. How does that change your approach?

Save to ▾
Show answer
I would test with real budget devices and network throttling rather than a fast laptop. The priorities become sending less JavaScript, rendering important content on the server, compressing images aggressively, and keeping the initial page under a strict size budget. Caching with a service worker helps repeat visits. Features like large animations and heavy carousels should be reduced or loaded only when the device can handle them.
18

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.
19

When should you use IndexedDB instead of localStorage?

Save to ▾
Show answer
localStorage is synchronous, stores only strings and is limited to about 5 MB, so large reads block the main thread. IndexedDB is asynchronous, stores structured data including blobs, supports indexes and transactions, and can hold hundreds of megabytes depending on disk space. Use it for offline data, drafts, cached API results or files in PWAs. Wrapper libraries like idb make its event-based API easier with promises.
20

Tailwind classes built dynamically like 'bg-' + colour work locally but are missing in production. Why?

Save to ▾
Show answer
Tailwind finds classes by scanning source files for complete strings, so a class assembled at runtime never appears in the code and its CSS is not generated. The fix is to map values to full class names, such as const colours = { success: 'bg-green-600', error: 'bg-red-600' }. If truly dynamic values are needed, use inline styles with CSS variables or explicitly safelist those classes.
21

How do environment variables work in frontend builds, and what is the risk?

Save to ▾
Show answer
Build tools replace variables at build time, for example Vite exposes only variables prefixed with VITE_ through import.meta.env. The values become plain text inside the JavaScript bundle that anyone can read. So frontend environment variables must never hold secrets like private API keys or database passwords; those belong on a server or backend proxy. Use them only for public configuration such as API base URLs.
22

Compare CSS Modules, CSS-in-JS and utility-first CSS.

Save to ▾
Show answer
CSS Modules scope class names per file at build time, giving plain CSS with no runtime cost. CSS-in-JS libraries write styles in JavaScript with dynamic props, but runtime versions add bundle size and slow server rendering, so zero-runtime options are now preferred. Utility-first frameworks like Tailwind compose small classes in markup, producing small CSS and consistent spacing. The choice depends on team preference and rendering strategy.
23

Your app needs to support Hindi and English. How do you design internationalisation?

Save to ▾
Show answer
I would move all UI text into translation files keyed by message ids, use an i18n library that supports plurals and interpolation, and format numbers, dates and currency with Intl APIs for each locale, like en-IN and hi-IN. Layouts must handle longer text and Devanagari fonts with proper line height. The locale goes in the URL, such as /hi/, with hreflang tags for SEO and lang on html.
24

Explain preload, prefetch and preconnect.

Save to ▾
Show answer
preconnect opens an early connection, including DNS, TCP and TLS, to an important third-party origin like a font or API server. preload fetches a resource needed for the current page at high priority, such as the hero image or main font. prefetch downloads resources likely needed for the next navigation at low priority during idle time. Overusing preload wastes bandwidth and can delay more critical resources.
25

Errors from failed promises are silently disappearing in production. How do you catch them?

Save to ▾
Show answer
Promises without a catch produce unhandled rejections that do not stop the app but hide failures. I would add a global window.addEventListener('unhandledrejection') handler and window.onerror that report errors to a monitoring tool like Sentry with source maps. In code, every async call should have try and catch or a .catch, and ESLint rules such as no-floating-promises in TypeScript projects catch missing handlers.
26

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.
27

How would you migrate a large JavaScript codebase to TypeScript?

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

What are generics and why are they useful?

Save to ▾
Show answer
Generics let you write reusable code that keeps type information, using type parameters like <T>. For example, function first<T>(items: T[]): T | undefined returns a number for a number array and a User for a User array without losing types. Constraints such as <T extends { id: string }> restrict what T can be. Generics power typed API clients, form libraries and reusable UI components.
29

Define brand design tokens in Tailwind CSS v4.

Save to ▾
Show answer
Tokens go in CSS with the @theme directive: @import 'tailwindcss'; @theme { --color-brand-500: #2563eb; --color-brand-700: #1d4ed8; --font-display: 'Poppins', sans-serif; --radius-card: 12px; } /* usage in markup */ /* <button class='bg-brand-500 hover:bg-brand-700 rounded-card font-display'> */ Tailwind generates utilities like bg-brand-500 from these variables and also exposes them as CSS custom properties for use in plain CSS.
30

What are higher-order functions and currying?

Save to ▾
Show answer
A higher-order function takes a function as an argument or returns one, like map, filter or a custom withLogging(fn) wrapper. Currying transforms a function with many arguments into a chain of single-argument functions, so add(2)(3) returns 5. Currying makes partial application easy, for example creating formatINR = formatCurrency('INR') once and reusing it. Overusing it can reduce readability for teams unfamiliar with functional style.
31

Compare Promise.all, Promise.allSettled, Promise.race and Promise.any.

Save to ▾
Show answer
Promise.all resolves with all results when every promise succeeds, but rejects immediately if any fails. Promise.allSettled always waits for all and returns each outcome with status fulfilled or rejected, useful for dashboards loading independent widgets. Promise.race settles with the first promise to settle, often used for timeouts. Promise.any resolves with the first success and rejects only if all fail, useful for trying multiple mirrors.
32

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.
33

Tell me about a time you learned a new browser API to deliver a feature.

Save to ▾
Show answer
Situation: during my internship, the team wanted product images to load only when visible. Task: I was asked to implement it without adding a library. Action: I studied IntersectionObserver on MDN, built a small prototype, measured the page in Lighthouse and then applied it to the listing page with a fallback. Result: initial page weight dropped by about 60 percent, and the pattern was reused on other pages.
34

What are declaration files (.d.ts) and when do you write them?

Save to ▾
Show answer
Declaration files describe the types of JavaScript code without containing implementation. Libraries ship them so TypeScript users get type checking, and many come from DefinitelyTyped as @types packages. You write your own when using an untyped library, declaring global variables injected by scripts, or typing non-code imports like declare module '*.svg'. Generating them with declaration: true is standard when publishing a TypeScript library.
35

Tell me about a time you convinced your team to adopt a new tool like TypeScript.

Save to ▾
Show answer
Situation: our JavaScript app kept breaking after API changes. Task: I believed TypeScript would help but the team worried about slowing down. Action: I converted one small module as a pilot, showed three bugs it caught, and proposed gradual adoption with no deadline pressure. Result: the team agreed, we migrated over two quarters, and production errors related to wrong data shapes dropped significantly.
36

The build works on your machine but fails in CI. How do you troubleshoot?

Save to ▾
Show answer
I would compare environments first: Node version, package manager version, and whether CI uses npm ci with the committed lockfile while I used npm install. Other common causes are case-sensitive file paths on Linux, missing environment variables, and files ignored by Git. Pinning Node with an .nvmrc or engines field and reproducing the CI command locally in a clean clone or container usually reveals the difference.

Frequently asked questions

Which companies hire Frontend Development professionals in Kolkata?

Companies with large offices in Kolkata include many IT services and product firms. Use their company pages below to practise employer-specific sets.

Are Frontend Development interviews in Kolkata different from other cities?

The questions depend more on the company than the city. Kolkata's mix of employers decides the style: Many openings are with service companies and their delivery centres, with a focus on strong fundamentals

How do I find Frontend Development jobs in Kolkata?

Shortlist companies with Kolkata offices, keep your CV focused on Frontend Development projects, apply on company career pages and job portals with the Kolkata filter, and practise the questions on this page before each interview.