MakeMyTrip Frontend Development Interview Questions & Answers
Curated interview practice questions with answers. These are practice scenarios, not a verified list of past interview questions.
About MakeMyTrip hiring for Frontend Development roles
MakeMyTrip is an Indian online travel company offering flights, hotels, holidays, buses and trains, and it also owns Goibibo and redBus. Its technology and analytics teams work on search, pricing, personalisation and customer service. It hires for software engineers, SDETs, business analysts and data scientists.
For Frontend Development roles, this MakeMyTrip practice set focuses most on Web Performance (5), Frontend Testing (4), Modern JavaScript (4), TypeScript (4). It has 20 medium, 10 hard questions, so you can start easy and work up to the harder ones.
Company type
E-commerce & consumer tech
Headquarters
Gurugram, India
Main India offices
Gurugram, Bengaluru
MakeMyTrip Frontend Development interview process
Online assessment (coding or SQL)
Technical round 1
Technical round 2 or case round
Hiring manager round
HR round
Typical pattern based on public candidate experiences. Rounds vary by role, team and year.
Solved for MakeMyTripStart 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
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.
02
Write a fetch wrapper that retries with exponential backoff.
I would run a bundle analyser to see what is inside. Usual wins are route-based code splitting, lazy loading heavy widgets, replacing large libraries such as full date or utility packages with smaller alternatives or native APIs, and importing only needed functions so tree shaking works. I would also remove polyfills for browsers we no longer support, and make sure production mode and minification are enabled.
04
Marketing has added many third-party scripts and the site has become slow. What do you do?
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.
05
npm audit reports a critical vulnerability in a dependency. What do you do?
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.
06
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.
07
How do HTTP/2 and HTTP/3 change frontend bundling strategy?
HTTP/1.1 allowed few parallel requests per domain, so developers concatenated everything into one big bundle and used domain sharding. HTTP/2 multiplexes many requests over one connection, and HTTP/3 runs over QUIC to avoid head-of-line blocking on lossy mobile networks. This makes moderate chunk splitting efficient and improves caching, because changing one module invalidates only its chunk. Still, too many tiny files add overhead.
08
How does the History API enable client-side routing?
history.pushState(state, '', '/courses/react') changes the URL and adds a history entry without reloading the page, and replaceState updates the current entry. When users press back or forward, the popstate event fires and the app renders the matching view. The server must return the app's HTML for all routes, otherwise refreshing a deep link gives a 404. Routers in SPA frameworks are built on this API.
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.
10
Create a type where all fields are optional except id.
Coverage shows which lines ran, not whether the behaviour was verified, so tests can execute code without meaningful assertions. I would explain this with an example and propose a balanced target, perhaps 80 percent on business logic, combined with quality measures like mutation testing, critical user flows covered by end-to-end tests and tracking escaped defects. Effort is better spent on risky areas than on trivial getters.
12
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.
13
Break a long-running loop into smaller tasks to keep the page responsive.
Yield to the main thread between chunks:
function yieldToMain() {
if (globalThis.scheduler?.yield) return scheduler.yield();
return new Promise(resolve => setTimeout(resolve, 0));
}
async function processRows(rows) {
let last = performance.now();
for (const row of rows) {
processRow(row);
if (performance.now() - last > 40) {
await yieldToMain();
last = performance.now();
}
}
}
The browser can handle clicks between chunks, which improves INP. scheduler.yield keeps the task's priority after resuming.
14
Add automated accessibility checks to Playwright tests.
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.
15
Configure cache headers for hashed assets and HTML in Nginx.
Long cache for fingerprinted files, revalidation for HTML:
location ~* \.(js|css|woff2|avif|webp|svg)$ {
add_header Cache-Control 'public, max-age=31536000, immutable';
}
location / {
try_files $uri /index.html;
add_header Cache-Control 'no-cache';
}
This works only when build tools add content hashes to filenames. Returning users then load assets from cache instantly, while every deploy still reaches them through fresh HTML.
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.
17
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.
18
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.
19
After a release, the app shows a blank page in some older browsers. What could be wrong?
The build probably targets newer syntax or uses an API that older browsers lack, causing a parse error that stops the whole bundle. I would check the console in that browser, compare the build target and browserslist with our support policy, and add missing polyfills for used APIs. Error monitoring with browser breakdowns catches this quickly, and testing on the oldest supported browser should be part of release checks.
20
What is the guiding principle of Testing Library and why query by role?
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.
21
Your team uses 'as any' everywhere to silence errors. How do you improve this?
I would first understand why: often the real types are unclear or the API response is untyped. I would add shared API types, introduce unknown with type guards for external data, and enable the ESLint rule no-explicit-any as a warning. Then I would fix the most risky areas first and block new any in CI. Showing a bug that types would have caught helps get team buy-in.
22
Users in India see order dates shifted by a day. What is the likely bug?
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.
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.
24
Search results sometimes show data for an older query. What is happening?
This is a race condition: requests for 'ja' and 'java' are in flight together, and if the older one responds last, it overwrites the newer results. I would cancel the previous request with AbortController, or tag each request with an id and ignore responses that are not the latest. Debouncing the input reduces the number of requests, and caching repeated queries makes responses faster and more consistent.
25
What are CSS cascade layers and what problem do they solve?
Cascade layers, declared with @layer reset, base, components, utilities, let you control the order of priority between groups of styles regardless of selector specificity. A simple selector in a later layer beats a highly specific selector in an earlier layer. This solves specificity wars between resets, third-party libraries and your components, without resorting to !important. Unlayered styles win over all layered ones.
26
When should you use IndexedDB instead of localStorage?
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.
27
How do private class fields and getters work in modern JavaScript?
Fields prefixed with #, such as #balance, are truly private and cannot be accessed outside the class body, unlike the old underscore convention. Getters and setters, written get total() and set total(v), let you expose computed or validated properties while keeping internal state hidden. Static fields and static blocks are also supported. These features make classes safer for building reusable UI components and service objects.
28
Write a GitHub Actions workflow that lints, tests and builds a frontend app.
A typical CI pipeline:
name: CI
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm test -- --run
- run: npm run build
npm ci installs exactly from the lockfile, and caching speeds up repeat runs. Branch protection can require this check before merging.
Design tokens are named values for design decisions, such as color-primary, space-4 or radius-md, stored in one place and shared by designers and developers. They are often kept in JSON and converted into CSS custom properties, Tailwind theme values or mobile platform formats. Changing a token updates every component consistently, which makes rebranding or dark mode much easier than hunting hard-coded values.
30
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.
Tips to crack the MakeMyTrip Frontend Development interview
Prepare cases on travel funnels, such as drop-offs between search and booking or hotel conversion rates.
Practise testing scenarios for booking flows, including fare changes, payments, cancellations and refunds across flights and hotels.
Read about MakeMyTrip, Goibibo and redBus to understand its multi-brand travel business.
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; MakeMyTrip interviewers usually ask follow-ups on your first answer.
Frequently asked questions
How many rounds are there in the MakeMyTrip Frontend Development interview?
Candidates usually go through 5 stages: Online assessment (coding or SQL); Technical round 1; Technical round 2 or case round; 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 MakeMyTrip Frontend Development interview?
This practice set leans on Web Performance (5), Frontend Testing (4), Modern JavaScript (4), TypeScript (4). Revise those first, then practise explaining one or two of your own projects end to end, because most MakeMyTrip interviewers ask you to walk through real work.
Are these the exact questions asked at MakeMyTrip?
No. These are curated practice questions that match the skills and difficulty usually tested in e-commerce & consumer tech interviews like MakeMyTrip's. They are not a leaked or verified list of past questions.
Where does MakeMyTrip hire Frontend Development professionals in India?
MakeMyTrip has large teams in Gurugram, Bengaluru. Openings and locations change often, so check the MakeMyTrip careers page and filter by city and experience.
Frontend Development questions for similar companies