Skip to content

MERN Stack Developer Interview Questions & Answers

40 questions for MERN Stack Developer interviews — 22 easy, 18 medium.

About the MERN Stack Developer role

A MERN Stack Developer builds complete features across the stack: MongoDB schemas, Express APIs and React screens. Day to day you turn designs and requirements into working pages, connect them to REST endpoints, handle authentication and fix bugs reported by QA. This is the most common entry role at startups and IT service companies, and it rewards developers who can take a feature from database to deployment with clean, tested code.

React components REST APIs MongoDB queries JWT auth Git
Solved for this roleStart 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

What is MongoDB and how is it different from a relational database?

Save to ▾
Show answer
MongoDB is a document database that stores data as flexible JSON-like documents in collections instead of rows in fixed tables. Related data can be embedded in one document, so many reads need no joins. Schemas are flexible, horizontal scaling through sharding is built in, and it supports indexes, aggregation and multi-document ACID transactions. Relational databases fit strongly structured data with many relationships and complex joins.
02

Write an aggregation that counts orders and sums revenue per status.

Save to ▾
Show answer
Group by status and sort by revenue. db.orders.aggregate([ { $match: { createdAt: { $gte: ISODate('2026-01-01') } } }, { $group: { _id: '$status', orders: { $sum: 1 }, revenue: { $sum: '$amount' } } }, { $sort: { revenue: -1 } }, { $project: { status: '$_id', orders: 1, revenue: 1, _id: 0 } } ]) In Mongoose the same array goes into Order.aggregate([...]).
03

You are building a registration form with ten fields and validation. How do you manage its state?

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

What are the common ways to render content conditionally in React?

Save to ▾
Show answer
Use an early return for whole-component cases like loading, an if statement outside JSX, the ternary operator for either-or markup, and logical && for show-or-hide. Be careful with && on numbers: count && <Badge /> renders 0 when count is zero, so use count > 0 && <Badge />. For many states, map a status value to components with an object lookup.
05

What is a closure and where is it useful?

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

Write a Mongoose schema for a user with validation and timestamps.

Save to ▾
Show answer
A typical schema: import mongoose from 'mongoose'; const userSchema = new mongoose.Schema({ name: { type: String, required: true, trim: true, maxlength: 60 }, email: { type: String, required: true, unique: true, lowercase: true }, password: { type: String, required: true, minlength: 8, select: false }, role: { type: String, enum: ['user', 'admin'], default: 'user' } }, { timestamps: true }); export const User = mongoose.model('User', userSchema); select: false hides the password from queries by default.
07

What are the core principles of a RESTful API, and which HTTP methods are idempotent?

Save to ▾
Show answer
REST models data as resources identified by URLs, uses standard HTTP methods, is stateless, and returns representations like JSON with proper status codes. Use nouns, for example GET /orders and POST /orders. GET, PUT, DELETE, HEAD and OPTIONS are idempotent: repeating them gives the same server state. POST is not idempotent, and PATCH usually is not, which matters when clients retry requests.
08

Write a register endpoint that hashes the password with bcrypt.

Save to ▾
Show answer
Validate, check duplicates and hash before saving. import bcrypt from 'bcrypt'; router.post('/register', async (req, res) => { const { name, email, password } = req.body; if (!email || !password || password.length < 8) { return res.status(400).json({ message: 'Invalid input' }); } const exists = await User.findOne({ email: email.toLowerCase() }); if (exists) return res.status(409).json({ message: 'Email already registered' }); const hash = await bcrypt.hash(password, 12); const user = await User.create({ name, email, password: hash }); res.status(201).json({ id: user._id, name: user.name }); }); A unique index on email still guards against races.
09

Which HTTP status codes should a REST API commonly return?

Save to ▾
Show answer
Use 200 OK for successful reads and updates, 201 Created after a POST that creates a resource, and 204 No Content for successful deletes. Use 400 for invalid input, 401 when authentication is missing or invalid, 403 when the user is authenticated but not allowed, 404 for missing resources, 409 for conflicts such as duplicate email, 422 for validation errors, 429 for rate limits and 500 for unexpected server errors.
10

How does React protect against XSS and where can XSS still happen?

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

Build a simple todo list in React with add and delete.

Save to ▾
Show answer
Update arrays immutably. function Todos() { const [todos, setTodos] = useState([]); const [text, setText] = useState(''); const add = (e) => { e.preventDefault(); if (!text.trim()) return; setTodos((t) => [...t, { id: crypto.randomUUID(), text }]); setText(''); }; const remove = (id) => setTodos((t) => t.filter((x) => x.id !== id)); return ( <form onSubmit={add}> <input value={text} onChange={(e) => setText(e.target.value)} /> <ul>{todos.map((t) => ( <li key={t.id}>{t.text} <button type='button' onClick={() => remove(t.id)}>x</button></li> ))}</ul> </form> ); }
12

How do you protect a public Express API from abuse and brute-force traffic?

Save to ▾
Show answer
Add rate limiting with express-rate-limit, using a Redis store when running multiple instances, and apply stricter limits to login and OTP routes. Set request body size limits, validate all input, require authentication on non-public routes, add helmet headers and timeouts. At the edge, a CDN or web application firewall can block bots and DDoS traffic before it reaches Node. Return 429 with a Retry-After header.
13

A client wants deleted records to be recoverable. How would you implement soft delete with Mongoose?

Save to ▾
Show answer
Add fields like isDeleted: Boolean with default false and deletedAt: Date. The delete endpoint sets these instead of removing the document. Add a pre-find query middleware that filters isDeleted: false by default, and an admin route to restore. Include isDeleted in relevant indexes or use partial indexes, for example a unique email index that only applies to non-deleted users. Purge old records with a scheduled job.
14

Why does the order of middleware matter in Express?

Save to ▾
Show answer
Express runs middleware and routes in the order they are registered. If express.json() is added after your routes, req.body will be undefined. Authentication middleware must come before protected routes, static file serving usually comes early, a 404 handler comes after all routes, and the error-handling middleware must be registered last. If a middleware neither sends a response nor calls next(), the request hangs.
15

What is the difference between useMemo and useCallback?

Save to ▾
Show answer
useMemo caches the result of a calculation, recomputing only when dependencies change, for example a filtered and sorted list. useCallback caches a function reference, so useCallback(fn, deps) equals useMemo(() => fn, deps). They help when passing values or callbacks to memoized children or as effect dependencies. They have their own cost, so do not wrap everything; the React Compiler can now add this memoization automatically.
16

What is JSX and how is it converted into JavaScript?

Save to ▾
Show answer
JSX is a syntax extension that lets you write HTML-like markup inside JavaScript. A compiler such as Babel, esbuild or SWC, used by Vite, turns each element into a function call that creates a React element object. JSX supports JavaScript expressions inside curly braces, uses className instead of class and htmlFor instead of for, and requires one parent element or a fragment.
17

Walk me through a MERN project you built, end to end.

Save to ▾
Show answer
Situation: I built a job portal as my major project. Task: let recruiters post jobs and students apply with resumes. Action: I designed MongoDB collections for users, jobs and applications with indexes, built an Express REST API with JWT auth and role checks, a React frontend with React Router and TanStack Query, uploaded resumes to cloud storage, wrote API tests and deployed with Docker. Result: 60 classmates used it during placement season.
18

What is a Buffer in Node.js?

Save to ▾
Show answer
A Buffer is a fixed-size chunk of raw binary memory allocated outside the V8 heap, used for files, network packets, images and encodings. You create one with Buffer.from('hello') or Buffer.alloc(10) and convert with toString('utf8'), toString('base64') or toString('hex'). Streams deliver data as Buffers by default. Buffer.allocUnsafe is faster but may contain old memory, so it must be filled before use.
19

Write an asyncHandler wrapper for Express 4 route handlers.

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

Two sibling components need to share data. How do you handle it?

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

Write a reusable validation middleware for Express using zod.

Save to ▾
Show answer
Validate before the controller runs and return 400 on failure. import { z } from 'zod'; const validate = (schema) => (req, res, next) => { const result = schema.safeParse(req.body); if (!result.success) { return res.status(400).json({ errors: result.error.issues }); } req.body = result.data; next(); }; const userSchema = z.object({ name: z.string().min(2), email: z.string().email() }); router.post('/users', validate(userSchema), createUser);
22

What are the important changes in Express 5 compared to Express 4?

Save to ▾
Show answer
Express 5 requires a modern Node version and forwards rejected Promises from async handlers to error middleware. Route path syntax moved to a newer path-to-regexp, so wildcards must be named, like /*splat, and regex-style characters in strings are no longer supported. Deprecated methods like res.send(status, body) were removed, req.query is read-only, and req.body is undefined unless a body parser runs.
23

How does routing work in a React single-page app using React Router?

Save to ▾
Show answer
React Router maps URL paths to components without full page reloads. You define routes, often with createBrowserRouter or Routes and Route elements, including nested routes that render inside a parent layout through Outlet. Link and NavLink change the URL, useNavigate navigates in code, and useParams reads dynamic segments like /products/:id. Recent versions also provide loaders and actions for data fetching and form submission.
24

What does the helmet middleware do in Express?

Save to ▾
Show answer
helmet sets HTTP security headers in one line: Content-Security-Policy to restrict script sources, Strict-Transport-Security to force HTTPS, X-Content-Type-Options nosniff, X-Frame-Options or frame-ancestors to prevent clickjacking, and Referrer-Policy. It also removes the X-Powered-By header that reveals Express. It is not a complete security solution, but it is a cheap, standard first layer in every production API.
25

Implement page-based pagination for a products API with Mongoose.

Save to ▾
Show answer
Return items plus metadata. async function listProducts(req, res) { const page = Math.max(1, Number(req.query.page) || 1); const limit = Math.min(50, Number(req.query.limit) || 10); const [items, total] = await Promise.all([ Product.find().sort({ createdAt: -1 }) .skip((page - 1) * limit).limit(limit).lean(), Product.countDocuments() ]); res.json({ items, page, totalPages: Math.ceil(total / limit) }); } Capping limit prevents clients from requesting huge pages.
26

After deploying a React app, refreshing on a page like /dashboard shows a 404 error. Why, and how do you fix it?

Save to ▾
Show answer
With client-side routing, /dashboard exists only inside React Router, not as a file on the server. When the browser requests it directly, the web server finds no file and returns 404. Configure the server to fall back to index.html for unknown paths: try_files $uri /index.html in Nginx, a rewrite rule on static hosts, or a catch-all route in Express that serves index.html after the API routes.
27

Write an Express router with CRUD routes for a products resource.

Save to ▾
Show answer
Keep routes thin and delegate to a controller. import { Router } from 'express'; import * as ctrl from '../controllers/product.controller.js'; const router = Router(); router.get('/', ctrl.list); router.get('/:id', ctrl.getById); router.post('/', ctrl.create); router.patch('/:id', ctrl.update); router.delete('/:id', ctrl.remove); export default router; // app.js app.use(express.json()); app.use('/api/v1/products', router);
28

Write Express middleware that logs method, URL, status code and response time.

Save to ▾
Show answer
Hook into the response finish event to know the final status. function requestLogger(req, res, next) { const start = process.hrtime.bigint(); res.on('finish', () => { const ms = Number(process.hrtime.bigint() - start) / 1e6; console.log(`${req.method} ${req.originalUrl} ${res.statusCode} ${ms.toFixed(1)}ms`); }); next(); } app.use(requestLogger); In production, use a structured logger like pino instead of console.log.
29

Why does React need keys in lists, and why is using the array index risky?

Save to ▾
Show answer
Keys tell React which list item is which between renders, so it can reuse, move or remove the correct DOM nodes and component state. Use stable unique ids, such as a MongoDB _id. Index keys break when items are inserted, removed or reordered: state such as input text or checkbox values can attach to the wrong item, and rendering becomes less efficient. Indexes are acceptable only for static lists.
30

How would you structure the folders of a production Express API?

Save to ▾
Show answer
A layered structure keeps responsibilities clear: src/routes for route definitions, src/controllers for request and response handling, src/services for business logic, src/models for Mongoose schemas, src/middlewares for auth, validation and errors, src/config for environment and database setup, src/utils for helpers, and tests alongside or in a tests folder. Keep app.js, which builds the app, separate from server.js, which listens, so tests can import the app.
31

What does lifting state up mean in React?

Save to ▾
Show answer
When two or more components need the same data, you move that state to their closest common parent and pass it down as props, along with functions to update it. For example, a filter bar and a product list both depend on the selected category, so the page component holds the category state. This keeps one source of truth and avoids components getting out of sync.
32

Fetch a list of users from an API inside useEffect with proper cleanup.

Save to ▾
Show answer
AbortController cancels the request if the component unmounts. function Users() { const [users, setUsers] = useState([]); const [error, setError] = useState(null); useEffect(() => { const controller = new AbortController(); fetch('/api/users', { signal: controller.signal }) .then((r) => r.json()) .then(setUsers) .catch((e) => { if (e.name !== 'AbortError') setError(e); }); return () => controller.abort(); }, []); if (error) return <p>Failed to load</p>; return <ul>{users.map((u) => <li key={u._id}>{u.name}</li>)}</ul>; }
33

Tell me about a time you received critical feedback on your UI code and how you responded.

Save to ▾
Show answer
Situation: in my internship, a senior reviewer rejected my pull request because my components were large and repeated logic. Task: fix it without missing the sprint deadline. Action: I asked for examples, split the page into smaller components, extracted a custom hook for the shared fetching logic and added prop types. Result: the PR was approved the next day, and the reviewer used my hook in another feature.
34

A developer accidentally pushed the .env file with the MongoDB password and JWT secret to a public repository. What do you do?

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

How do class component lifecycle methods map to hooks?

Save to ▾
Show answer
componentDidMount maps to useEffect with an empty dependency array. componentDidUpdate maps to useEffect with specific dependencies. componentWillUnmount maps to the cleanup function returned from useEffect. shouldComponentUpdate is roughly React.memo, and getDerivedStateFromProps is usually replaced by computing values during render. The mindset shifts from lifecycle moments to synchronising with external systems whenever certain values change.
36

How should passwords be stored, and why use bcrypt?

Save to ▾
Show answer
Never store plain or reversibly encrypted passwords. Store a slow, salted hash. bcrypt generates a random salt per password, so identical passwords produce different hashes and rainbow tables fail, and its cost factor, typically 10 to 12, makes brute force expensive. At login use bcrypt.compare. Argon2id is a modern alternative. Fast hashes like MD5 or SHA-256 alone are unsuitable for passwords.
37

What is a JWT and what are its three parts?

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

What is the difference between props and state in React?

Save to ▾
Show answer
Props are inputs passed from a parent to a child component; they are read-only inside the child. State is data owned and managed by a component itself, created with useState or useReducer, and changing it triggers a re-render. A common pattern is that a parent keeps state and passes both the value and a setter function down as props to children.
39

How do you protect certain routes in React so that only logged-in users can access them?

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

What is React and how does the virtual DOM help performance?

Save to ▾
Show answer
React is a JavaScript library for building user interfaces from reusable components. When state changes, React re-renders components into a lightweight in-memory tree called the virtual DOM, compares it with the previous tree through reconciliation, and applies only the minimal changes to the real DOM. Direct DOM updates are expensive, so batching and diffing keep updates efficient while letting developers write declarative code.

Frequently asked questions

What does a MERN Stack Developer do?

A MERN Stack Developer builds complete features across the stack: MongoDB schemas, Express APIs and React screens. Day to day you turn designs and requirements into working pages, connect them to REST endpoints, handle authentication and fix bugs reported by QA. This is the most common entry role at startups and IT service companies, and it rewards developers who can take a feature from database to deployment with clean, tested code.

Which skills are tested in a MERN Stack Developer interview?

Expect questions on React components, REST APIs, MongoDB queries, JWT auth, Git. Most rounds also ask you to explain a project and solve one practical problem live.

How do I prepare for a MERN Stack Developer interview?

Revise Express.js and REST APIs, MongoDB and Mongoose, React Fundamentals, Authentication and Security first using the topic sheets, practise the questions on this page aloud, then do one full mock interview to practise timing.