Node.js interviews begin with the event loop and asynchronous code, then move to APIs, error handling, streams, performance, and security. The most common reason candidates stumble is describing the event loop as magic. A clear explanation of what runs where, and what blocks, is what interviewers listen for.
Below are 24 questions with answers. Code samples are short so you can type them from memory.
Event loop and async
1. What is Node.js?
A JavaScript runtime built on Chrome's V8 engine that runs outside the browser. It uses a single-threaded event loop for JavaScript with non-blocking I/O, which makes it good at handling many connections that spend most of their time waiting.
2. How does the event loop work?
JavaScript code runs on one thread. When it starts an I/O operation such as reading a file or making a request, Node hands it to the system or a thread pool and continues. When the operation finishes, its callback is queued, and the event loop runs it when the call stack is empty. The loop moves through phases: timers, pending callbacks, poll (I/O), check (setImmediate), and close callbacks.
3. What's the order of process.nextTick, Promises, setTimeout, and setImmediate?
console.log('1 sync');
setTimeout(() => console.log('4 timeout'), 0);
setImmediate(() => console.log('5 immediate'));
Promise.resolve().then(() => console.log('3 promise'));
process.nextTick(() => console.log('2 nextTick'));
Synchronous code runs first. Then process.nextTick callbacks, then promise microtasks, then the loop phases. setTimeout(0) versus setImmediate can vary in the main module, but inside an I/O callback setImmediate always runs first. Be ready to explain rather than only recite.
4. What does "blocking the event loop" mean, and how do you avoid it?
A long synchronous task, such as a huge JSON parse, a big loop, or fs.readFileSync in a request handler, stops all other requests until it finishes. Avoid it by using async APIs, breaking work into chunks, or moving CPU-heavy work to worker threads or another process.
5. Callbacks, promises, and async/await: what are the differences?
Callbacks are the original style and can nest deeply. Promises represent a future value and chain with then. async/await is syntax on top of promises that reads like synchronous code and works with try/catch.
6. How do you run async tasks in parallel?
const [user, orders] = await Promise.all([getUser(id), getOrders(id)]);
Promise.all rejects if any fail. Promise.allSettled waits for all and reports each result. Promise.race returns the first to settle. Don't await inside a loop when the calls are independent.
7. What's the difference between worker threads, child processes, and cluster?
Worker threads run JavaScript in separate threads in one process and can share memory, which suits CPU-heavy work. Child processes start separate programs. The cluster module forks several copies of the app, one per core, sharing a port, so you can use all CPUs for handling requests.
Modules and tooling
8. CommonJS versus ES modules?
CommonJS uses require and module.exports and loads synchronously. ES modules use import and export, are the standard in JavaScript, and support top-level await. Node supports both, chosen by file extension or the type field in package.json.
9. What's in package.json, and what's the difference between dependencies and devDependencies?
It holds metadata, scripts, and dependencies. dependencies are needed at runtime, and devDependencies only for development and testing. A lock file records exact versions so installs are reproducible.
10. How do you handle environment configuration?
Use environment variables, read through process.env, with a validated config module. Keep secrets out of the repository, and use a secrets manager in production.
APIs and Express
11. What is middleware in Express?
A function with access to the request, the response, and next. Middleware runs in order and can modify the request, end the response, or pass control on. Typical uses are logging, parsing bodies, authentication, and error handling.
app.use((req, res, next) => {
console.log(req.method, req.url);
next();
});
12. How do you handle errors in an Express app?
Catch errors in async handlers and pass them to next(err), then use an error-handling middleware with four arguments (err, req, res, next) to send a consistent response. In Express 5, rejected promises from handlers are forwarded automatically. For uncaught exceptions and unhandled rejections, log and restart the process rather than continue in an unknown state.
13. How would you design a REST API endpoint to create an order?
Validate input, authenticate the user, check permissions, create the order inside a database transaction, return 201 with the new resource and its location, handle duplicates with an idempotency key, and return clear errors with proper status codes.
14. How do you authenticate users?
Sessions with cookies, or tokens such as JWTs. Hash passwords with a slow algorithm such as bcrypt or argon2. With JWTs, keep expiry short, use refresh tokens carefully, and don't store sensitive data in the token.
Streams, files, and performance
15. What are streams, and why use them?
Streams process data in chunks instead of loading it all into memory. Types are readable, writable, duplex, and transform. Use them for large files, uploads, and downloads.
const fs = require('node:fs');
const { pipeline } = require('node:stream/promises');
const zlib = require('node:zlib');
await pipeline(fs.createReadStream('in.log'), zlib.createGzip(), fs.createWriteStream('in.log.gz'));
16. What is backpressure?
When a writable stream can't keep up with a readable one, it signals the source to slow down. pipeline and pipe handle this for you. If you write manually, check the return value of write() and wait for the drain event.
17. How do you find a memory leak?
Watch memory over time, take heap snapshots (Chrome DevTools or --inspect), and compare them to see which objects grow. Common causes are global caches that never expire, event listeners that aren't removed, and closures holding large objects.
18. How do you scale a Node.js application?
Run several processes with the cluster module or a process manager, put them behind a load balancer, keep the app stateless by moving sessions to Redis or a database, use caching, and scale out with containers. Move CPU-heavy work to workers or separate services.
19. How do you profile a slow endpoint?
Measure first with logs and timings, then use --prof or --cpu-prof, or a flame graph tool, to find hot functions. Check database queries, since the slowness is more often there than in JavaScript.
Security and reliability
20. What are common Node.js security issues?
Injection (SQL, NoSQL, command), cross-site scripting, weak authentication, vulnerable dependencies, secrets in code, missing rate limiting, and unsafe deserialization. Mitigate with input validation, parameterized queries, helmet, dependency audits (npm audit), and the principle of least privilege.
21. How do you shut down gracefully?
On SIGTERM, stop accepting new connections, let in-flight requests finish, close database connections, and then exit, with a timeout as a fallback.
process.on('SIGTERM', () => {
server.close(() => process.exit(0));
});
22. How do you test Node.js code?
Unit tests with a runner such as the built-in node:test, Jest, or Vitest, mocking external calls. Integration tests against a test database and HTTP-level tests with a tool such as Supertest. Keep tests fast and independent.
Design and scenario
23. Your API is slow under load. How do you investigate?
Check metrics for latency and CPU. If CPU is high on one core, look for blocking code or heavy JSON work. If CPU is low and latency is high, look at waiting on the database or other services. Then add caching, indexes, connection pooling, or batching, and test again under load.
24. How would you build a file upload endpoint for large files?
Stream the upload straight to storage, such as object storage with a pre-signed URL, instead of buffering it in memory. Set size limits, validate type, scan if needed, and process afterward in a background job.
How to prepare
Write a small API with authentication, a database, and an upload route, then profile it with a load tool and fix one problem. Practice drawing the event loop and explaining the output of a small script like the one above. Prepare one real story about debugging a performance or reliability issue. For coding rounds, see our coding interview assistant guide, and for design, the system design guide.
Say your answers aloud and read the transcript for places where you used a term without explaining it. Follow the employer's rules on AI tools in any live interview.
Practice Node.js interview answers with YesToTheOffer
Run a mock technical interview, explain the event loop out loud, and review your transcript afterward. 30 free minutes, no subscription.



