Node.js Coding Interview Questions You Can’t Ignore
2025-08-23
Node.js interviews tend to be practical. You’ll be asked not just to solve problems but also to show you understand how Node really works under the hood — async behavior, event loop, streams, and real-world API handling. Here are the Node.js coding interview questions you can’t ignore, with short explanations and code snippets you can adapt.
1) Explain the Event Loop in Node.js
Question: How does the Node.js event loop handle asynchronous tasks?
Answer: Node is single-threaded for JavaScript execution. It offloads I/O to the libuv thread pool, then the event loop picks callbacks from phases like timers, pending callbacks, idle/prepare, poll, check, and close callbacks.
Demo Code:
console.log("start");
setTimeout(() => console.log("timeout"), 0);
Promise.resolve().then(() => console.log("promise"));
console.log("end");
// Order: start -> end -> promise -> timeout
Talking point: microtasks (Promise.then
) run before timers.
2) Difference Between process.nextTick()
and setImmediate()
setImmediate(() => console.log("setImmediate"));
process.nextTick(() => console.log("nextTick"));
console.log("sync");
// Order: sync -> nextTick -> setImmediate
Key difference: nextTick
queues to the microtask queue, setImmediate
to the check phase.
3) How to Handle Errors in Async Code
Question: How do you safely catch errors in promises and async/await?
// Using promises
fetchData()
.then(res => console.log(res))
.catch(err => console.error("Error:", err));
// Using async/await
async function main() {
try {
const data = await fetchData();
console.log(data);
} catch (err) {
console.error("Error:", err);
}
}
Talking point: Always return or await promises to propagate errors.
4) Build a Simple HTTP Server
const http = require("http");
const server = http.createServer((req, res) => {
if (req.url === "/") {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Hello, Node.js!");
}
});
server.listen(3000, () => console.log("Server running on 3000"));
Question angle: be ready to extend this with routes, JSON response, or error handling.
5) Difference Between CommonJS and ES Modules
// CommonJS
const fs = require("fs");
// ES Module
import fs from "fs";
Talking point: Node 14+ supports ES modules with "type": "module"
in package.json
. CommonJS is synchronous; ESM is async and supports tree-shaking.
6) How Do Streams Work in Node.js
Question: What are the types of streams?
- Readable
- Writable
- Duplex
- Transform
Demo Code:
const fs = require("fs");
const read = fs.createReadStream("input.txt");
const write = fs.createWriteStream("output.txt");
read.pipe(write);
Talking point: streams reduce memory footprint by processing chunks.
7) Explain Clustering in Node.js
const cluster = require("cluster");
const http = require("http");
const os = require("os");
if (cluster.isPrimary) {
os.cpus().forEach(() => cluster.fork());
} else {
http.createServer((req, res) => res.end("Worker " + process.pid)).listen(3000);
}
Talking point: clustering lets Node scale across CPU cores, but memory is not shared. Use a load balancer or external store for shared state.
8) JWT Authentication Middleware Example
const jwt = require("jsonwebtoken");
function auth(req, res, next) {
const token = req.headers["authorization"];
if (!token) return res.status(401).send("No token");
try {
req.user = jwt.verify(token, "secret");
next();
} catch {
res.status(403).send("Invalid token");
}
}
Talking point: use middleware for modularity, always store secrets in env variables.
9) What is Middleware in Express.js
const express = require("express");
const app = express();
app.use((req, res, next) => {
console.log("Time:", Date.now());
next();
});
app.get("/", (req, res) => res.send("Hello Express"));
app.listen(3000);
Talking point: middleware functions take (req, res, next)
and can transform requests, add logging, or enforce security.
10) Implement Rate Limiting
const rateLimit = {};
const WINDOW = 60000;
const LIMIT = 5;
function limiter(req, res, next) {
const ip = req.ip;
const now = Date.now();
rateLimit[ip] = (rateLimit[ip] || []).filter(ts => now - ts < WINDOW);
if (rateLimit[ip].length >= LIMIT) return res.status(429).send("Too many requests");
rateLimit[ip].push(now);
next();
}
Talking point: in production, use Redis or a distributed store for horizontal scaling.
11) How Does Async I/O Differ From Multithreading
Answer: Node delegates I/O (disk, network) to the libuv thread pool. Threads are used behind the scenes, but JavaScript execution remains single-threaded. Use worker threads module for CPU-intensive tasks.
12) Worker Threads for CPU-bound Tasks
const { Worker } = require("worker_threads");
const worker = new Worker(`
const { parentPort } = require("worker_threads");
let sum = 0;
for (let i = 0; i < 1e9; i++) sum += i;
parentPort.postMessage(sum);
`, { eval: true });
worker.on("message", msg => console.log("Sum:", msg));
Talking point: worker threads isolate computation without blocking the main loop.
13) Handling Environment Variables
require("dotenv").config();
console.log("DB Host:", process.env.DB_HOST);
Talking point: never hardcode secrets. Use process.env
and a .env
file in dev, secret managers in prod.
14) Implement a Simple Pub/Sub with EventEmitter
const EventEmitter = require("events");
const bus = new EventEmitter();
bus.on("greet", name => console.log("Hello", name));
bus.emit("greet", "Alice");
Talking point: EventEmitter is core to Node, useful for async messaging inside apps.
15) Testing in Node.js
// sum.js
function sum(a, b) { return a + b; }
module.exports = sum;
// sum.test.js
const sum = require("./sum");
test("adds numbers", () => {
expect(sum(2, 3)).toBe(5);
});
Talking point: Jest, Mocha, or built-in test runner (node --test
in Node 18+) are standard.
Final Note
If you’re preparing for Node.js interviews, focus on the event loop, async patterns, middleware, error handling, and scaling. Those are the core concepts that get tested again and again.
For practicing coding interviews where you want a clean Node.js solution with explanations right in the moment, you can use StealthCoder — it overlays solutions while you code so you can focus on reasoning and answering confidently.