Skip to content

MERN Full Stack Developer Interview Questions & Answers

40 questions for MERN Full Stack Developer interviews — 29 easy, 11 medium.

About the MERN Full Stack Developer role

Builds complete features across React frontend and Node.js backend with MongoDB. Designs screens and the APIs behind them, manages authentication flows, deploys the app and fixes issues end to end. Common in startups and product teams that want developers who can take a feature from idea to production without hand-offs.

React Node.js and Express MongoDB and Mongoose JWT auth Deployment basics
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

Explain ACID properties of a database transaction.

Save to ▾
Show answer
Atomicity means all operations in a transaction succeed or none do. Consistency means the database moves from one valid state to another, respecting constraints. Isolation means concurrent transactions do not see each other's partial work, controlled by isolation levels. Durability means committed data survives crashes. Money transfers rely on ACID so a debit never happens without the matching credit.
02

What is Express.js and why is it widely used?

Save to ▾
Show answer
Express is a minimal, unopinionated web framework for Node.js that adds routing, middleware and helpers for requests and responses on top of the http module. It is widely used because it is simple, flexible and has a large ecosystem of middleware for logging, auth, validation and security. Many teams also use it as the base for frameworks like NestJS.
03

How do you document a REST API?

Save to ▾
Show answer
Use the OpenAPI 3 specification, written by hand in YAML or generated from code or validation schemas, and serve it with Swagger UI or Redoc. Document each endpoint's parameters, request and response schemas, status codes, auth and examples. Keep it in the repo, validate it in CI and generate client SDKs or contract tests from it so docs never drift from the code.
04

What is the difference between app.use and app.get?

Save to ▾
Show answer
app.use mounts middleware for all HTTP methods and matches any path that starts with the given prefix, for example app.use('/api', router). app.get registers a handler only for GET requests on an exact route pattern. Use app.use for cross-cutting concerns like parsing and auth, and method-specific functions such as get, post, put and delete for endpoints.
05

A client reports that a large JSON POST request fails with 413 Payload Too Large. What do you do?

Save to ▾
Show answer
express.json() has a default body limit of 100 KB, so bigger payloads are rejected with 413. If the size is legitimate, raise it for that route only, for example express.json({ limit: '2mb' }), and check any proxy limit such as Nginx client_max_body_size. For very large data, switch to file upload to object storage or pagination instead of huge JSON bodies.
06

What is an index and how does it improve query performance?

Save to ▾
Show answer
An index is a data structure, usually a B-tree, that lets the database find rows without scanning the whole table or collection. Indexes speed up reads on filtered, sorted and joined fields but slow down writes and use storage. Create them based on real query patterns, check usage with EXPLAIN or explain('executionStats'), and remove unused ones.
07

Define a Mongoose schema for a user with validation and an index.

Save to ▾
Show answer
const { Schema, model } = require('mongoose'); const userSchema = new Schema({ name: { type: String, required: true, trim: true }, email: { type: String, required: true, unique: true, lowercase: true }, password: { type: String, required: true, select: false }, role: { type: String, enum: ['user', 'admin'], default: 'user' }, city: String }, { timestamps: true }); userSchema.index({ city: 1, createdAt: -1 }); module.exports = model('User', userSchema);
08

Write a simple request logging middleware that records response time.

Save to ▾
Show answer
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 pino-http or morgan with structured logs.
09

Explain semantic versioning and the meaning of ^ and ~ in package.json.

Save to ▾
Show answer
Semantic versioning uses MAJOR.MINOR.PATCH: major for breaking changes, minor for new backward-compatible features, patch for bug fixes. A caret like ^4.18.2 allows any 4.x.x at or above 4.18.2. A tilde like ~4.18.2 allows only patch updates, 4.18.x. An exact version pins it. The lock file still decides what is actually installed.
10

Why do you want to work as a Node.js backend developer?

Save to ▾
Show answer
I enjoy building the systems behind products: APIs, data models and integrations. Node.js lets me use JavaScript across the stack and ship features quickly, and I like solving problems around performance and reliability. In my projects I built a REST API with authentication, MongoDB and Docker deployment, and I want to grow by working on real traffic and learning system design from experienced engineers.
11

What is the difference between PUT and PATCH?

Save to ▾
Show answer
PUT replaces the entire resource with the representation sent, so missing fields may be reset; it is idempotent. PATCH applies a partial update, sending only changed fields, such as { "phone": "..." }. PATCH is more efficient for large objects. With JSON Merge Patch, repeated identical PATCH requests are effectively idempotent, but operations like increment are not.
12

What is the difference between res.send, res.json and res.end?

Save to ▾
Show answer
res.send sends a response and sets Content-Type based on the argument: string as HTML, Buffer as binary, object as JSON. res.json always serialises to JSON and sets application/json, and respects app settings like json spaces. res.end ends the response with no extra processing, useful for empty responses such as 204. Call only one per request to avoid headers-already-sent errors.
13

How would you structure a large Express project?

Save to ▾
Show answer
I use a layered structure: routes define endpoints, controllers handle HTTP details, services hold business logic, and repositories or models talk to the database. Add middlewares, validators, config and utils folders, and group by feature, for example modules/orders, once the app grows. This keeps controllers thin, makes services unit-testable and avoids business rules leaking into routes.
14

How do you handle a situation where you cannot find the root cause of a bug before a deadline?

Save to ▾
Show answer
I inform my lead early with what I know, what I have ruled out and the risk. I propose a safe mitigation, such as a feature flag to disable the path or a rollback, and add extra logging to capture more data. In one case this let us release on time with the feature off, and the new logs revealed the cause two days later.
15

A mobile app team complains your API returns too much data and is slow on 4G. What would you change?

Save to ▾
Show answer
Add field selection like ?fields=id,name,price, smaller list representations with details on a separate endpoint, pagination with sensible limits and gzip or Brotli compression. Support ETag and Cache-Control so unchanged data returns 304. If many screens need combined data, consider a Backend-for-Frontend layer or GraphQL tailored to the mobile app.
16

What is Redis and how is it used with Node.js backends?

Save to ▾
Show answer
Redis is an in-memory key-value store with data types like strings, hashes, lists, sets, sorted sets and streams. Node apps use it for caching database results, session storage, rate limiting counters, distributed locks, leaderboards, pub/sub between instances and job queues through BullMQ. Data lives in memory, so use TTLs and eviction policies and do not treat it as the only copy of important data.
17

Explain the main HTTP methods and which are idempotent.

Save to ▾
Show answer
GET reads a resource, POST creates or triggers an action, PUT replaces a resource fully, PATCH updates part of it and DELETE removes it. GET, PUT, DELETE, HEAD and OPTIONS are idempotent, meaning repeating the request has the same effect as doing it once. POST and usually PATCH are not, which is why payment APIs use idempotency keys for POST.
18

What is the difference between req.params, req.query and req.body?

Save to ▾
Show answer
req.params holds route parameters from the path, such as id in /users/:id. req.query holds query string values like ?page=2&sort=name, used for filtering and pagination. req.body holds the parsed request payload of POST, PUT or PATCH and needs a parser such as express.json(). All are user input and must be validated before use.
19

How do you explain asynchronous programming to a non-technical stakeholder or junior teammate?

Save to ▾
Show answer
I use a restaurant analogy. One waiter takes an order, gives it to the kitchen and serves other tables instead of waiting at the stove; when the dish is ready, the kitchen rings a bell. Node.js works the same: it starts a database or network task, handles other requests and resumes when the result is ready. Then I show a short code example with async and await.
20

After adding a new middleware, all routes return 404 or hang. How do you debug it?

Save to ▾
Show answer
A hang usually means the middleware never calls next() or sends a response on some path. A 404 often means it was mounted with a wrong path or registered after routes. I check order of app.use calls, add logging at the start and end of the middleware, verify every branch calls next or responds, and check async code passes errors to next.
21

Why put Nginx in front of a Node.js application?

Save to ▾
Show answer
Nginx acts as a reverse proxy: it terminates TLS, serves static files efficiently, compresses responses, buffers slow clients, load balances across multiple Node instances and adds rate limiting and request size limits. This frees Node to focus on application logic. On cloud platforms a managed load balancer or ingress controller often plays the same role.
22

How do you keep yourself updated about security best practices as a backend developer?

Save to ▾
Show answer
I follow the Node.js security release announcements and OWASP cheat sheets, read GitHub security advisories for packages we use and keep Dependabot alerts on. I also practise with labs like OWASP Juice Shop. In my last project I used this to propose helmet, rate limits and stricter input validation, and I shared a short security checklist that the team adopted in pull request reviews.
23

What is the difference between SQL and NoSQL databases?

Save to ▾
Show answer
SQL databases such as PostgreSQL and MySQL store data in tables with fixed schemas, support joins and strong ACID transactions, and suit relational data like orders and payments. NoSQL databases such as MongoDB, Redis or Cassandra use documents, key-value or wide-column models with flexible schemas and easier horizontal scaling. The choice depends on data relationships, consistency needs and query patterns.
24

What is a compound index and why does field order matter?

Save to ▾
Show answer
A compound index covers multiple fields, such as { userId: 1, createdAt: -1 }. It supports queries that use a prefix of the fields, so it helps queries on userId alone or userId plus createdAt, but not createdAt alone. A good rule in MongoDB is ESR: put equality fields first, then sort fields, then range fields, to avoid in-memory sorts.
25

What is the difference between REST and GraphQL?

Save to ▾
Show answer
REST exposes multiple endpoints with fixed response shapes, uses HTTP caching easily and is simple to reason about. GraphQL exposes one endpoint where clients query exactly the fields they need, reducing over-fetching and multiple round trips, which helps mobile apps. GraphQL adds complexity: N+1 query risks needing DataLoader, harder caching, query cost limits and schema governance.
26

How do you design good REST endpoint URLs?

Save to ▾
Show answer
Use plural nouns for resources and let methods express the action: GET /users, POST /users, GET /users/42, PATCH /users/42. Nest only for clear ownership, like GET /users/42/orders, and avoid deep nesting. Use lowercase kebab-case, query parameters for filtering, sorting and pagination, and version the API, for example /api/v1. Avoid verbs like /getUsers.
27

What is Mongoose and why use it with MongoDB?

Save to ▾
Show answer
Mongoose is an ODM for MongoDB in Node.js. It adds schemas with types, validation, defaults, middleware hooks such as pre save, virtuals, population of references and a convenient query API. This brings structure to schemaless MongoDB collections and reduces bugs. For very high-performance or simple cases, some teams use the native MongoDB driver directly to avoid the overhead.
28

What is middleware in Express?

Save to ▾
Show answer
Middleware is a function with the signature (req, res, next) that runs during the request-response cycle. It can read or modify req and res, end the response, or call next() to pass control to the next middleware. Typical uses are parsing JSON, logging, authentication, CORS and rate limiting. Order matters, because middleware runs in the sequence it is registered.
29

Why is using async callbacks inside forEach a common bug?

Save to ▾
Show answer
Array.forEach ignores the promise returned by an async callback, so it does not wait for any iteration and errors are not caught by the outer function. Code after the loop runs before the work is done. Use for...of with await for sequential processing, or map the items to promises and await Promise.all for parallel processing.
30

What is a REST API and what are its key constraints?

Save to ▾
Show answer
REST is an architectural style where resources are identified by URLs and manipulated through standard HTTP methods. Key constraints: client-server separation, statelessness so each request carries all needed information, cacheable responses, uniform interface, layered system and optionally code on demand. In practice it means resource-based URLs, correct methods and status codes, and JSON representations.
31

Write a parameterised query with node-postgres to fetch a user's recent orders.

Save to ▾
Show answer
const { Pool } = require('pg'); const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 10 }); async function recentOrders(userId, limit = 10) { const { rows } = await pool.query( `SELECT id, amount, status, created_at FROM orders WHERE user_id = $1 ORDER BY created_at DESC LIMIT $2`, [userId, limit] ); return rows; }
32

What causes the error 'Cannot set headers after they are sent to the client'?

Save to ▾
Show answer
It happens when code tries to send a second response for the same request, for example calling res.json in a callback and then again later, or forgetting return after sending an error response, or calling next() after responding. Fix it by returning immediately after each res.send or res.json, and making sure each code path sends exactly one response.
33

How do you enable CORS in an Express app and why is it needed?

Save to ▾
Show answer
Browsers block cross-origin requests unless the server sends CORS headers. Use the cors package: app.use(cors({ origin: ['https://app.example.com'], credentials: true })). Avoid origin '*' with credentials, and restrict methods and headers you allow. CORS is a browser protection, not a security layer for your API, so you still need authentication and authorisation.
34

Compare Prisma, Sequelize and TypeORM for SQL databases in Node.js.

Save to ▾
Show answer
Prisma uses a schema file to generate a fully typed client and has excellent TypeScript support and migrations, though complex raw SQL needs escape hatches. Sequelize is mature, promise-based and widely used in older JavaScript projects. TypeORM uses decorators and entity classes, familiar to Java and NestJS developers. Drizzle is a newer lightweight, SQL-like typed option. Pick based on TypeScript use and team familiarity.
35

What is database normalisation and when would you denormalise?

Save to ▾
Show answer
Normalisation organises tables to remove duplicate data and update anomalies, typically up to third normal form, for example keeping customers and orders in separate tables linked by foreign keys. You denormalise for read performance, such as storing a product name on an order line or a precomputed order count on a user, when joins become expensive. Denormalised data must be kept in sync.
36

How does error-handling middleware work in Express?

Save to ▾
Show answer
Error-handling middleware has four parameters (err, req, res, next) and must be registered after all routes. When any middleware calls next(err) or throws in a synchronous handler, Express skips normal middleware and jumps to the error handler. In Express 4, async errors must be passed to next manually or with a wrapper; Express 5 forwards rejected promises automatically.
37

How do you use express.Router to organise routes?

Save to ▾
Show answer
// routes/users.js const router = require('express').Router(); router.get('/', listUsers); router.get('/:id', getUser); router.post('/', auth, createUser); module.exports = router; // app.js app.use(express.json()); app.use('/api/v1/users', require('./routes/users')); // Keeps each resource in its own module with its own middleware.
38

Design endpoints for a simple e-commerce cart and checkout.

Save to ▾
Show answer
GET /api/v1/cart returns the current user's cart. POST /api/v1/cart/items adds an item with productId and quantity. PATCH /api/v1/cart/items/:itemId changes quantity, and DELETE removes it. POST /api/v1/orders creates an order from the cart with an Idempotency-Key header. GET /api/v1/orders/:id shows status, and POST /api/v1/orders/:id/cancel handles cancellation as an action.
39

What are the common strategies for API versioning?

Save to ▾
Show answer
URL versioning like /api/v1/orders is the most common and easy to route and cache. Header versioning uses a custom header or Accept media type, keeping URLs clean but less visible. Query versioning like ?version=2 is simple but messy. Whatever you choose, version only for breaking changes, support old versions for a deprecation period and announce sunset dates.
40

What does helmet do in an Express application?

Save to ▾
Show answer
helmet is middleware that sets secure HTTP response headers. It adds Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options nosniff, frame protection and removes X-Powered-By, reducing risks like clickjacking, MIME sniffing and some XSS attacks. It is one line, app.use(helmet()), but CSP usually needs tuning so your frontend scripts and assets still load.

Frequently asked questions

What does a MERN Full Stack Developer do?

Builds complete features across React frontend and Node.js backend with MongoDB. Designs screens and the APIs behind them, manages authentication flows, deploys the app and fixes issues end to end. Common in startups and product teams that want developers who can take a feature from idea to production without hand-offs.

Which skills are tested in a MERN Full Stack Developer interview?

Expect questions on React, Node.js and Express, MongoDB and Mongoose, JWT auth, Deployment basics. Most rounds also ask you to explain a project and solve one practical problem live.

How do I prepare for a MERN Full Stack Developer interview?

Revise Express.js Framework, REST API Design, Databases: MongoDB, SQL and Redis first using the topic sheets, practise the questions on this page aloud, then do one full mock interview to practise timing.