36 practice questions with answers for MERN Stack interviews in Mumbai.
MERN Stack jobs in Mumbai
Mumbai is India's financial capital, so banks, fintechs, insurers, media and consulting firms drive much of the hiring. Data and QA interviews often include domain questions on payments, risk, trading or customer analytics.
Below are 36 questions that match the mix of service, product and domain employers hiring mern stack developers in Mumbai.
Solved for MumbaiStart 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 an asyncHandler wrapper for Express 4 route handlers.
It catches rejected Promises and forwards them to error middleware.
const asyncHandler = (fn) => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
router.get('/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) return res.status(404).json({ message: 'Not found' });
res.json(user);
}));
Express 5 does this automatically, but many existing codebases still use this pattern.
02
Your API has 40 routes and each returns errors in a different format. How would you standardise this?
Create a custom AppError class with statusCode and code fields, throw it from services and controllers, and handle every error in one central error middleware that returns a consistent shape such as { success: false, error: { code, message, details } }. Map validation, Mongoose cast and duplicate key errors to proper status codes there. Document the format in OpenAPI so the React team handles errors uniformly.
A closure is a function that remembers the variables of the scope where it was created, even after that outer function has returned. For example, a makeCounter function can return an inner function that increments a private count variable. Closures power data privacy, function factories, memoization, debounce and throttle helpers, and React hooks, where event handlers capture props and state from the render that created them.
04
Tell me about a time you had to deliver a frontend feature under a tight deadline.
Situation: a client demo was moved two days earlier and our filters page was half done. Task: deliver a working version in time. Action: I agreed a reduced scope with the lead, reused existing components, built the three most-used filters first and wrote quick tests for them, and kept the team updated each evening. Result: the demo went well and the remaining filters shipped in the next sprint.
05
Create an AuthContext with a provider and a custom hook.
Node 18 and later ship a global fetch. Use AbortSignal.timeout to cancel slow requests.
async function getJSON(url) {
try {
const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
if (err.name === 'TimeoutError') console.error('Request timed out');
throw err;
}
}
Without a timeout, a hung upstream can hold connections open indefinitely.
07
Describe a production issue you handled in a Node.js service.
Situation: our order API started timing out every evening at peak. Task: as the on-call developer I had to restore it. Action: I checked logs and metrics, found event-loop lag spikes, and traced them to a synchronous CSV export running inside a request. I moved the export to a background job and added event-loop lag alerts. Result: p95 latency dropped from 4 seconds to 300 ms and timeouts stopped.
08
A component calls setState inside useEffect and the app goes into an infinite render loop. Why?
The effect updates state, which re-renders, which runs the effect again. This happens when the dependency array is missing, or when a dependency is a new object or array created every render, or when the effect sets the same state it depends on. Add correct dependencies, move object creation inside the effect or memoize it, and ask whether the value can be calculated during render instead.
09
A developer accidentally pushed the .env file with the MongoDB password and JWT secret to a public repository. What do you do?
Treat the secrets as compromised immediately. Rotate the MongoDB user password, the JWT secret and any API keys; rotating the JWT secret logs everyone out, which is acceptable. Check database and cloud logs for suspicious access. Remove the file, add .env to .gitignore, and purge it from history with a tool like git filter-repo, though rotation matters more. Enable secret scanning and pre-commit hooks to prevent repeats.
10
Create a basic HTTP server in Node.js without Express that returns JSON.
The built-in node:http module is enough for simple servers.
import http from 'node:http';
const server = http.createServer((req, res) => {
if (req.method === 'GET' && req.url === '/health') {
res.writeHead(200, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ status: 'ok' }));
}
res.writeHead(404);
res.end();
});
server.listen(3000, () => console.log('Listening on 3000'));
Express adds routing, middleware and body parsing on top of this.
11
What does lean() do in Mongoose and when should you use it?
By default Mongoose queries return full documents with change tracking, getters, virtuals and methods like save. Calling .lean() returns plain JavaScript objects, which uses much less memory and is noticeably faster. Use it for read-only endpoints such as lists and API responses. Skip it when you need to modify and save the document, or depend on virtuals and getters unless you add a lean plugin.
12
You are building a registration form with ten fields and validation. How do you manage its state?
For a simple form, keep a single state object and update fields with a shared handler using the input name, for example setForm({ ...form, [e.target.name]: e.target.value }). Validate on blur and submit, storing errors in another object. For larger forms, use React Hook Form with a zod schema, which reduces re-renders and shares the validation schema with the Express backend.
13
How does React protect against XSS and where can XSS still happen?
React escapes values rendered in JSX, so user text containing script tags is shown as text, not executed. XSS can still happen through dangerouslySetInnerHTML with unsanitised HTML, javascript: URLs in href attributes, injecting user data into script tags during SSR, or unsafe third-party scripts. Sanitise any HTML with DOMPurify, validate URLs, set a Content Security Policy, and keep tokens out of JavaScript-readable storage.
Supertest sends HTTP requests directly to your Express app object without starting a real server on a port, and lets you assert on status codes, headers and bodies. This is why you export the app separately from the server.listen call. Combine it with an in-memory MongoDB using mongodb-memory-server or a dedicated test database, seeding data before each test and clearing it afterwards.
15
Group an array of order objects by their status using reduce.
reduce builds an object whose keys are statuses and values are arrays.
const grouped = orders.reduce((acc, order) => {
(acc[order.status] ||= []).push(order);
return acc;
}, {});
// { paid: [...], pending: [...] }
Newer runtimes also offer Object.groupBy(orders, (o) => o.status), which returns the same shape with a null prototype.
16
Duplicate user accounts with the same email are being created even though the code checks for an existing email first. Why, and how do you fix it?
Check-then-insert is a race condition: two concurrent requests both see no user and both insert. The real fix is a unique index on email, normalised to lowercase, so the database rejects the second insert with error code 11000. Catch that error and return 409 Conflict. Clean up existing duplicates before building the index, otherwise index creation fails.
17
What is Node.js and how does it handle many requests on a single thread?
Node.js is a JavaScript runtime built on the V8 engine and libuv. Your JavaScript runs on one main thread, but I/O such as network calls, file reads and database queries is non-blocking. Node hands that work to the operating system or the libuv thread pool and continues with other requests; callbacks run when results are ready. This makes it efficient for I/O-heavy APIs, but weak for CPU-heavy work.
18
The React app works locally but shows CORS errors after deployment. What would you check?
Check that the production frontend origin, including https and exact subdomain, is in the API's allowed origins list, and that no trailing slash mismatch exists. If cookies are sent, the server needs credentials: true with a specific origin, not *, and the client needs credentials: 'include' or withCredentials. Also confirm the preflight OPTIONS request is not blocked by a proxy or auth middleware returning 401.
React.memo wraps a component so it skips re-rendering when its props are shallowly equal to the previous props. It helps with expensive components that re-render often because the parent re-renders, such as rows in a large table. It fails if you pass new object, array or function props every render, so pair it with useMemo and useCallback. Measure with React DevTools Profiler before adding it.
20
A setInterval inside useEffect always logs the initial count value instead of the updated one. Why, and how do you fix it?
This is a stale closure: the effect ran once with an empty dependency array, so its callback captured count from the first render forever. Fixes include using the functional updater setCount((c) => c + 1) so you do not need to read count, adding count to the dependencies with proper cleanup, or storing the latest value in a ref that the interval reads.
21
How do you set up npm scripts for development and production in a Node.js API?
Define scripts in package.json and run them with npm run.
"scripts": {
"dev": "node --watch --env-file=.env src/server.js",
"start": "node src/server.js",
"lint": "eslint .",
"test": "vitest run"
}
Modern Node has a built-in --watch flag, so nodemon is optional. npm start and npm test work without the run keyword.
A JSON Web Token is a compact, URL-safe token made of three Base64URL-encoded parts separated by dots: the header with algorithm and type, the payload with claims like sub, role and exp, and the signature created from the header and payload using a secret or private key. The signature proves the token was not altered, but the payload is readable by anyone, so never put passwords or sensitive data in it.
23
Tell me about a time you improved the performance of a slow database-driven feature.
Situation: our admin orders page took 8 seconds to load. Task: I was asked to fix it within a sprint. Action: I profiled the API, found a populate on every row plus an unindexed sort, added a compound index, replaced populate with a single $lookup projecting only needed fields, and used lean. Result: load time dropped below 600 ms and I shared an indexing checklist with the team.
24
Two sibling components need to share data. How do you handle it?
Lift the shared state to their nearest common parent and pass the value to one sibling and an updater to the other. If the data is needed by many components deep in the tree, use Context or a state library like Zustand or Redux Toolkit. If the data comes from the server, a data-fetching library like TanStack Query can share the cached result across components.
25
The business wants total sales per category for the last 30 days. How would you build it in MongoDB?
Use an aggregation pipeline: $match orders with status paid and createdAt in the last 30 days, using an index on createdAt; $unwind the items array; $group by items.category summing items.price times items.qty; then $sort by total descending. If the report is viewed often, precompute daily totals into a summary collection with a scheduled job or $merge, so the dashboard reads small documents.
26
How do you implement code splitting in a React app?
Use dynamic import with React.lazy, for example const Admin = lazy(() => import('./Admin')), and wrap it in a Suspense boundary with a fallback. Bundlers like Vite then create a separate chunk that loads only when needed. Split by route first, then by heavy components like charts, editors and maps. Preload likely next routes on hover, and check results with a bundle analyser such as rollup-plugin-visualizer.
27
Tell me about a time you found and fixed a security issue in an application.
Situation: while testing an order history feature, I noticed changing the order id in the URL showed another user's order. Task: fix this insecure direct object reference before release. Action: I added an ownership check in the service layer so queries always filter by the logged-in user's id, wrote tests for cross-user access, and reviewed similar endpoints. Result: we fixed four endpoints and added ownership checks to our review checklist.
28
How do you protect certain routes in React so that only logged-in users can access them?
Create a ProtectedRoute or layout component that reads auth state from context. If the user is not authenticated, return <Navigate to='/login' replace state={{ from: location }} />, otherwise render the Outlet or children. Show a loader while the session check is pending to avoid flicker. Remember that this is only for user experience; real protection must happen on the Express API by verifying tokens on every request.
29
Write a Supertest integration test for a POST /api/users endpoint.
Keep config in environment variables, following the twelve-factor approach. Locally, load a .env file with dotenv or Node's built-in --env-file flag, and add .env to .gitignore while committing a .env.example. In production, inject variables through the hosting platform or a secrets manager. Validate all required variables at startup with a schema library like zod so the app fails fast with a clear message.
32
When should you use useReducer instead of useState?
Use useReducer when state has multiple related fields, when the next state depends on complex logic, or when many event handlers update state in different ways. A reducer is a pure function (state, action) => newState that centralises transitions and is easy to unit test, for example a cart with add, remove, change quantity and clear actions. For simple independent values, useState is clearer.
33
Your script crashes with out of memory while reading a 5 GB log file. How would you rewrite it?
fs.readFile loads the whole file into memory, which exceeds the heap. Use a stream instead: fs.createReadStream with readline lets you process one line at a time with for await, keeping memory flat. If you need to transform and write output, connect read, transform and write streams with pipeline so backpressure and errors are handled. Increasing --max-old-space-size only hides the real problem.
34
Attackers are trying thousands of passwords on your login endpoint. How do you defend it?
Apply strict rate limits on login per IP and per account using a shared Redis store, add progressive delays or temporary account lockout after several failures, and show a CAPTCHA after repeated attempts. Return a generic error message so attackers cannot tell whether an email exists. Log and alert on spikes, check for breached passwords at signup, and offer two-factor authentication for sensitive accounts.
35
Implement page-based pagination for a products API with Mongoose.
Which companies hire MERN Stack professionals in Mumbai?
Companies with large offices in Mumbai include TCS, Accenture, Capgemini, LTIMindtree, Paytm, Razorpay. Use their company pages below to practise employer-specific sets.
Are MERN Stack interviews in Mumbai different from other cities?
The questions depend more on the company than the city. Mumbai's mix of employers decides the style: Data and QA interviews often include domain questions on payments, risk, trading or customer analytics
How do I find MERN Stack jobs in Mumbai?
Shortlist companies with Mumbai offices, keep your CV focused on MERN Stack projects, apply on company career pages and job portals with the Mumbai filter, and practise the questions on this page before each interview.