Software Engineer | 46 questions | 2026
Node.js Interview Questions and Answers
Node.js interview questions for freshers 20
Q1FresherMost askedAnswerHideWhat is Node.js, and why is it called single-threaded and non-blocking?
Node.js is a JavaScript runtime built on Chrome's V8 engine. It lets you run JavaScript outside the browser, mostly for servers and tools.
Your JavaScript runs on one main thread, driven by an event loop. "Non-blocking" means slow operations (file, network, database) are handed to the operating system or libuv's thread pool. A callback or promise continues the work when they finish. The main thread stays free to serve other requests.
This makes Node good for I/O-heavy workloads: APIs, real-time chat, streaming, proxies. It is a poor fit for long CPU-heavy work (image processing, heavy maths) on the main thread. That work blocks every request. For that use worker threads, a job queue or another service.
What they are checking: Whether you understand the model, including its weakness
Q2FresherMost askedAnswerHideWhat is middleware in Express? How does it work?
Middleware is a function (req, res, next) that runs between receiving a request and sending the response. It can read or modify req and res, end the response, or call next() to pass control on.
const express = require("express");
const app = express();
app.use(express.json()); // parse JSON body
app.use((req, res, next) => { // logger
console.log(req.method, req.url);
next();
});
app.get("/users/:id", auth, (req, res) => res.json({ id: req.params.id }));
app.use((err, req, res, next) => { // error middleware (4 args)
res.status(500).json({ error: "Server error" });
});
Order matters: middleware runs in the order it is registered. Types: application level, router level, built-in, third-party (helmet, cors, morgan) and error handling (four parameters). Forgetting next() leaves the request hanging.
What they are checking: Whether you understand the request pipeline and ordering
Q3FresherMost askedAnswerHideWhat is the difference between blocking and non-blocking code, and synchronous and asynchronous APIs in Node?
Blocking code stops the thread until it finishes; nothing else on that thread can run. Non-blocking code starts the work and continues, with a callback, promise or event handling the result.
const fs = require("fs");
const data = fs.readFileSync("big.txt"); // blocks every request
fs.readFile("big.txt", (err, data) => {}); // callback
const d2 = await fs.promises.readFile("big.txt"); // promise
On a server, synchronous calls like readFileSync, pbkdf2Sync or a heavy JSON.parse stall all clients. They are acceptable at startup (loading config). Prefer the async versions in request handlers, and move CPU-heavy tasks to worker threads.
What they are checking: Whether you avoid blocking the loop
Q4FresherMost askedFree with sign-inAnswerHideWhat is the difference between CommonJS and ES modules in Node.js?
CommonJS (CJS) uses require() and module.exports, loads synchronously, and is the traditional Node format. ES modules (ESM) use import/export, are statically analysed, load asynchronously and are the language standard.
Q5FresherMost askedFree with sign-inAnswerHideWhat is the difference between package.json and package-lock.json? What do npm install and npm ci do?
package.json lists your direct dependencies with version ranges plus scripts and metadata. package-lock.json records the exact version of every dependency (including indirect ones) and integrity hashes. So every install gives the same tree.
Q6FresherMost askedFree with sign-inAnswerHideWhat is the difference between authentication and authorisation, and between sessions and tokens?
Authentication verifies who you are (login). Authorisation decides what you may do (roles, permissions, ownership).
Q7FresherMost askedFree with sign-inAnswerHideWhat is npm, and what are npm scripts and npx?
npm is Node's package manager and registry: it installs packages, runs scripts and publishes modules.
Q8FresherMost askedFree with sign-inAnswerHideWhat is a Buffer in Node.js?
A Buffer is a fixed-size chunk of raw binary data allocated outside the V8 heap. It is used for files, network packets, images and crypto, where data is bytes rather than strings.
Q9FresherMost askedFree with sign-inAnswerHideWhat is the difference between dependencies and devDependencies, and what do ^ and ~ mean?
dependencies are packages needed at run time (express, pg). devDependencies are only needed for development and build (jest, eslint, typescript). npm install --omit=dev skips the latter in production. peerDependencies declare packages the host project must supply (common in plugins).
Q10FresherMost askedFree with sign-inAnswerHideWhat is EventEmitter in Node.js?
EventEmitter (from the events module) is the base of Node's event-driven pattern. Objects emit named events and listeners react to them. Streams, HTTP servers and sockets all extend it.
Q11FresherMost askedFree with sign-inAnswerHideHow do you read a file in Node.js, and what is the difference between readFile and createReadStream?
const fs = require("fs/promises");
const text = await fs.readFile("data.txt", "utf8"); // whole file in memory
const stream = require("fs").createReadStream("big.csv", "utf8"); // chunks
readFileloads the full file into memory, which is simple and fine for small files such as config. -...
Q12FresherMost askedFree with sign-inAnswerHideHow do you manage configuration and environment variables in Node.js?
Keep configuration out of the code and read it from process.env, following the twelve-factor approach.
Q13FresherMost askedFree with sign-inAnswerHideWhat is CORS, and how do you enable it in Express?
CORS (Cross-Origin Resource Sharing) is a browser mechanism. By default a page from one origin cannot read responses from another origin. The server opts in with headers such as Access-Control-Allow-Origin. For non-simple requests the browser first sends an OPTIONS preflight.
Q14FresherMost askedFree with sign-inAnswerHideWhen would you choose Node.js over other backend technologies, and when not?
Choose Node.js for:
- I/O-bound APIs and microservices with many concurrent connections.
- Real-time features: chat, notifications, live dashboards (WebSocket, Server-Sent Events).
- Teams that already use JavaScript or TypeScript across frontend and backend, sharing types and code.
- Backends for frontends, serverless functions, proxies and tooling.
Q15FresherMost askedFree with sign-inAnswerHideWhat is the difference between module.exports and exports?
exports is a shortcut variable that initially points to the same object as module.exports. require() always returns module.exports.
Q16FresherMost askedFree with sign-inAnswerHideHow do you create an HTTP server without Express?
Use the built-in http module.
Q17FresherMost askedFree with sign-inAnswerHideHow do routing, route parameters and query strings work in Express?
Routes map an HTTP method and path to a handler. Use express.Router() to group related routes.
Q18FresherMost askedFree with sign-inAnswerHideWhat is the process object in Node.js and what do you use it for?
process is a global object that represents the running Node process.
Q19FresherMost askedFree with sign-inAnswerHideHow do you convert a callback-style function to use promises in Node.js?
Use util.promisify for functions that follow the Node convention (error first, callback last), or use the built-in promise APIs.
Q20FresherMost askedFree with sign-inAnswerHideHow would you deploy a Node.js application to a Linux server without Docker?
Run the app as a managed process behind a reverse proxy, with the code delivered by a repeatable script.
Node.js interview questions for experienced 17
Q21ExperiencedMost askedAnswerHideExplain the phases of the Node.js event loop.
The event loop is run by libuv and cycles through phases, each with a queue of callbacks:
- timers:
setTimeoutandsetIntervalcallbacks that are due. - pending callbacks: some deferred system I/O callbacks.
- idle, prepare: internal.
- poll: retrieves new I/O events and runs their callbacks; it may wait here if nothing else is scheduled.
- check:
setImmediatecallbacks. - close callbacks: for example
socket.on('close').
Between each callback (and after each phase transition) Node drains process.nextTick first, then promise microtasks.
setTimeout(() => console.log("timeout"), 0);
setImmediate(() => console.log("immediate"));
process.nextTick(() => console.log("tick"));
Promise.resolve().then(() => console.log("promise"));
// tick, promise, then timeout/immediate (order of the last two varies in the main module)
Inside an I/O callback, setImmediate always fires before setTimeout.
What they are checking: Whether you can name the phases and ordering
Q22ExperiencedMost askedAnswerHideWhat is the difference between process.nextTick(), setImmediate() and setTimeout(fn, 0)?
process.nextTick(fn)runs right after the current operation, before the event loop continues and before promise microtasks. Overusing it can starve I/O.setImmediate(fn)runs in the check phase, after the poll phase.setTimeout(fn, 0)runs in the timers phase after at least 1 ms.
Order of priority: nextTick, then promise microtasks, then timers/immediates.
- Use
nextTickto run something after the current function but before any I/O. One example is emitting an event after you return the emitter. - Use
setImmediateto yield to the event loop between chunks of work. - From the main module the order of
setTimeout 0andsetImmediateis not guaranteed; inside an I/O callbacksetImmediateis always first.
What they are checking: Whether you know the queue order
Q23ExperiencedMost askedAnswerHideWhat are streams in Node.js? Why and when would you use them?
A stream processes data in chunks instead of loading it all into memory. There are four types: Readable, Writable, Duplex (both) and Transform (modify data while passing through).
const { pipeline } = require("stream/promises");
const fs = require("fs");
const zlib = require("zlib");
await pipeline(
fs.createReadStream("input.log"),
zlib.createGzip(),
fs.createWriteStream("input.log.gz")
);
Use them for large files, uploads and downloads, HTTP request/response bodies, CSV processing and compression. Benefits: constant memory use and faster time to first byte. Use pipeline (not bare .pipe) so errors propagate and resources are cleaned up. Streams support backpressure: when the consumer is slow, write() returns false and the source pauses until drain.
What they are checking: Whether you can handle big data without exhausting memory
Q24ExperiencedMost askedAnswerHideWhat is the difference between the cluster module, worker threads and child processes?
All three use more CPU cores, but in different ways.
| cluster | worker_threads | child_process | |
|---|---|---|---|
| Unit | Multiple Node processes sharing a server port | Threads in one process | Separate OS process (any program) |
| Memory | Separate | Can share via SharedArrayBuffer | Separate |
| Best for | Scaling an HTTP server across cores | CPU-bound JavaScript work | Running shell commands or other programs |
| Communication | IPC messages | postMessage, shared memory | IPC, stdio |
const { Worker, isMainThread, parentPort, workerData } = require("worker_threads");
if (isMainThread) {
new Worker(__filename, { workerData: 40 }).on("message", console.log);
} else {
const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));
parentPort.postMessage(fib(workerData));
}
In production, cluster is often replaced by PM2 or containers with one process each behind a load balancer.
What they are checking: Whether you pick the right tool for I/O versus CPU work
Q25ExperiencedMost askedAnswerHideHow do you handle errors in Express, including async errors?
Use a central error-handling middleware with four arguments, registered last. Synchronous throws inside route handlers reach it automatically. In Express 4, rejected promises from async handlers do not, so wrap them or call next(err). Express 5 forwards rejected promises automatically.
const wrap = (fn) => (req, res, next) => fn(req, res, next).catch(next);
app.get("/users/:id", wrap(async (req, res) => {
const user = await db.find(req.params.id);
if (!user) { const e = new Error("Not found"); e.status = 404; throw e; }
res.json(user);
}));
app.use((err, req, res, next) => {
const status = err.status || 500;
res.status(status).json({ error: status === 500 ? "Internal error" : err.message });
});
Also: create custom error classes, log with context, and never leak stack traces to clients. Handle unhandledRejection and uncaughtException at process level, to log the error and exit cleanly.
What they are checking: Whether you handle async errors and avoid leaking details
Q26ExperiencedMost askedFree with sign-inAnswerHideHow does JWT authentication work in a Node.js API?
A JSON Web Token is a signed token with a header, payload (claims such as sub, exp) and signature. The server signs it after login; the client sends it on each request; the server verifies the signature and expiry without a session lookup.
Q27ExperiencedMost askedFree with sign-inAnswerHideHow do you secure a Node.js / Express application?
Layered measures:
Q28ExperiencedMost askedFree with sign-inAnswerHideHow would you scale a Node.js application?
Scale vertically first, then horizontally, and remove bottlenecks before adding servers.
Q29ExperiencedMost askedFree with sign-inAnswerHideHow do you handle unhandled rejections and uncaught exceptions, and implement graceful shutdown?
After an uncaughtException the process state may be inconsistent, so log it and exit; let a supervisor (PM2, Docker, Kubernetes) restart it. Since Node 15, unhandled promise rejections also crash the process by default.
Q30ExperiencedMost askedFree with sign-inAnswerHideHow does libuv and its thread pool fit into Node.js?
libuv is the C library that provides Node's event loop and asynchronous I/O across operating systems. Network I/O uses OS facilities (epoll, kqueue, IOCP) directly. Operations with no async OS API are run on libuv's thread pool, which has 4 threads by default.
Q31ExperiencedMost askedFree with sign-inAnswerHideHow would you add caching with Redis to a Node.js API?
Use the cache-aside pattern: check Redis, on a miss read the database and store the result with a TTL.
Q32ExperiencedMost askedFree with sign-inAnswerHideWhat is connection pooling and why does it matter for database access?
Opening a database connection is slow and databases limit concurrent connections. A pool keeps a set of open connections and lends them out, reusing them across requests.
Q33ExperiencedMost askedFree with sign-inAnswerHideHow do you test a Node.js API?
Use layers of tests.
Q34ExperiencedMost askedFree with sign-inAnswerHideHow do you do logging and monitoring in a Node.js service?
Use structured (JSON) logs and send them to a central system.
Q35ExperiencedMost askedFree with sign-inAnswerHideWhat is backpressure in Node.js streams, and how do you handle it?
Backpressure happens when a producer writes data faster than a consumer can handle. Without control, buffered data piles up in memory.
A writable stream signals this: write() returns false when its internal buffer passes highWaterMark. The producer should pause until the drain event, then resume.
Q36ExperiencedFree with sign-inAnswerHideWhat is the difference between spawn, exec, execFile and fork in child_process?
All start another process, but with different output handling.
Q37ExperiencedFree with sign-inAnswerHideWhat useful features have been added to recent Node.js versions?
Recent LTS releases reduced the need for extra packages:
Scenario based Node.js interview questions 9
Q38ExperiencedMost askedScenarioAnswerHideScenario: your Node.js service's memory keeps growing until it is killed (out of memory). How do you find and fix the leak?
Confirm it is a leak: memory climbs and does not drop after garbage collection. Then check process.memoryUsage() or metrics for heapUsed and RSS over time.
Find it:
- Run with
node --inspect, connect Chrome DevTools, and take heap snapshots under load a few minutes apart. Use the Comparison view to see which object types grow. Then read what keeps them alive (their retainers). - Or use
--heapsnapshot-signal=SIGUSR2in production-like environments, or tools such as clinic.js.
Typical causes:
- Unbounded in-memory caches or maps keyed by user id.
- Event listeners added per request and never removed (the "MaxListeners" warning is a hint).
- Closures holding large request objects, global arrays that accumulate, timers never cleared.
- Un-ended streams or unclosed connections.
Fix: bound caches (LRU with a max size and TTL) or move them to Redis, remove listeners, clear timers, close resources. Verify memory plateaus under load. Setting --max-old-space-size only delays the crash.
What they are checking: Whether you debug with heap snapshots, not guesses
Q39ExperiencedMost askedScenarioAnswerHideScenario: CPU usage is at 100% on one core and the API becomes slow. How do you diagnose and fix it?
Node runs your code on one thread, so a hot function blocks all requests.
Diagnose:
- Capture a CPU profile:
node --profandnode --prof-process,clinic flame, or Chrome DevTools via--inspect. Read the flame graph for the widest functions. - Check event loop lag (
perf_hooks.monitorEventLoopDelay) and which endpoint correlates with the spike.
Common culprits and fixes:
- Large
JSON.parse/stringify, sorting or looping over big arrays: paginate, stream, or process in chunks withsetImmediate. - Synchronous crypto or hashing: use async versions or worker threads.
- Catastrophic regex backtracking: fix the pattern or limit input size.
- Complex per-request computation: cache results, precompute, or move to a worker pool or separate service.
Then run one process per core (cluster or containers). That way one busy process does not take down all capacity. Add load tests to confirm the fix.
What they are checking: Whether you profile and know the single-thread consequence
Q40ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: an endpoint is fast in testing but slow under load, with high p99 latency. How do you investigate?
Work from measurement to cause.
Q41ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: users upload a 2 GB CSV that must be parsed and loaded into the database. How do you design it in Node.js?
Never buffer the whole file in memory. Stream it end to end and batch the writes.
Q42ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: how would you implement rate limiting per user for your Node.js API, running on several instances behind a proxy?
Counters must be shared across instances, so use a central store (Redis), not in-memory counters per process.
Q43ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: deploying a new version drops in-flight requests and users see errors. How do you get zero-downtime deployments?
Combine graceful shutdown with a rolling or blue-green deploy.
Q44ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: traffic suddenly spikes 10x because of a campaign. How do you keep the Node.js service up?
Act in layers, fastest wins first.
Q45ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: the server stops responding intermittently, yet CPU and memory look normal. What could be wrong?
Likely suspects:
Q46ExperiencedMost askedScenarioFree with sign-inAnswerHideScenario: a JWT was leaked or a user must be logged out immediately. How do you handle token revocation?
Stateless JWTs are valid until they expire, so revocation needs extra design.