Top Node.js Interview Questions Interview Questions | CandidateToHR
Master your backend Node.js interview. Covers event loop, streams, express, microservices architecture, and V8 performance.
CandidateToHR provides highly optimized, professional tech career resources. Build, customize, and analyze your tech career credentials completely free.
50 real-world Node.js interview questions, broken down by difficulty level for backend developers.
Top Interview Questions & Answers
Beginner Interview Questions
- Q: What is Node.js and how does it differ from traditional web servers?
- A: Node.js is an open-source, cross-platform runtime environment built on Chrome's V8 JavaScript engine. It allows developers to run JavaScript on the server side. Unlike traditional thread-based servers (like Apache) which spawn a new thread for each request, Node.js operates on a single-thread, non-blocking, event-driven architecture, making it highly efficient for I/O-heavy operations.
- Q: What is npm?
- A: NPM (Node Package Manager) is the default package manager for Node.js. It consists of a command-line client (`npm`) and an online database of public and paid-for private packages. It manages dependencies, versioning, and project scripts, encapsulated within the `package.json` file.
- Q: What is the `package.json` file?
- A: `package.json` is the manifest file of any Node.js project. It contains metadata about the project (name, version, author), defines scripts to run commands (like `npm start`), and lists all the dependencies (and devDependencies) required to run and build the application.
- Q: What is the difference between `dependencies` and `devDependencies`?
- A: `dependencies` are packages required for the application to run in production (e.g., Express, Mongoose). `devDependencies` are packages needed only during development and testing (e.g., Jest, Nodemon, ESLint). When deploying to production (`npm install --production`), devDependencies are not installed.
- Q: Explain `require()` vs `import()` in Node.js.
- A: `require()` is synchronous and resolves modules at runtime using the CommonJS module system (the traditional Node.js standard). `import()` is asynchronous and part of the newer ES Modules (ESM) standard introduced in ES6. Node.js now supports ESM natively if you set `"type": "module"` in `package.json`.
- Q: What are core modules in Node.js?
- A: Core modules are lightweight, built-in modules compiled into the Node.js binary. They can be loaded without installing any third-party packages. Examples include `fs` (File System), `http` (Networking), `path` (File paths), `crypto` (Cryptography), and `events` (Event Emitters).
- Q: What is Express.js?
- A: Express.js is a minimal and flexible Node.js web application framework. It provides a robust set of features for web and mobile applications, simplifying the creation of APIs, handling HTTP requests, defining routes, and managing middleware.
- Q: What is middleware in Express.js?
- A: Middleware functions are functions that have access to the request object (`req`), the response object (`res`), and the `next` middleware function in the application's request-response cycle. They can execute any code, make changes to req/res objects, end the cycle, or call `next()` to pass control to the next middleware.
- Q: What is an Event Emitter?
- A: The `EventEmitter` class in the `events` core module allows objects to emit named events that cause registered listeners (callback functions) to be called. It is the core concept behind Node's event-driven architecture. For example, an HTTP server acts as an EventEmitter that emits a 'request' event when a new connection is made.
- Q: Explain the `fs` module. Synchronous vs Asynchronous.
- A: The `fs` (File System) module interacts with the OS to read, write, and manipulate files. It provides both synchronous (`fs.readFileSync()`) and asynchronous (`fs.readFile()`) methods. Synchronous methods block the main thread until the file operation completes, which ruins Node's concurrency. Asynchronous methods use callbacks or promises and do not block the thread.
- Q: What is Nodemon?
- A: Nodemon is a utility that monitors for any changes in your source code and automatically restarts your server. It is strictly a development tool designed to drastically improve the developer experience by eliminating the need to manually stop and restart the Node.js process.
- Q: What is the global object in Node.js?
- A: In browsers, the global object is `window`. In Node.js, it is `global`. Variables declared with `var` at the top level are not added to the `global` object (unlike in browsers) because Node.js wraps files in module wrappers. The `global` object contains properties like `process`, `__dirname`, `__filename`, `setTimeout`, and `console`.
- Q: What is `process.env`?
- A: `process.env` is an object containing the user environment variables. In Node.js, it is commonly used to store configuration secrets like database URIs, API keys, and port numbers via a `.env` file (parsed using packages like `dotenv`), keeping sensitive data out of source code.
- Q: How do you handle errors in Node.js callbacks?
- A: Node.js follows an 'error-first callback' convention. The first argument of a callback function is always reserved for an error object. If the operation succeeds, the first argument is `null` and the result is passed as the second argument. Example: `fs.readFile('path', (err, data) => { if (err) throw err; })`.
- Q: What is REPL?
- A: REPL stands for Read Eval Print Loop. It represents a computer environment like a Windows console or Unix/Linux shell where a command is entered and the system responds with an output in an interactive mode. Typing `node` in the terminal opens the Node.js REPL.
- Q: What is the purpose of `module.exports`?
- A: `module.exports` is the object that is actually returned as the result of a `require` call. It allows you to expose functions, objects, or variables from one file so they can be imported and used in other files, forming the basis of the CommonJS module system.
- Q: What is semantic versioning (SemVer)?
- A: SemVer is the versioning system used by npm. Versions are written as MAJOR.MINOR.PATCH (e.g., 1.4.2). PATCH increments for backward-compatible bug fixes. MINOR increments for backward-compatible new features. MAJOR increments for breaking, non-backward-compatible changes. The `^` and `~` symbols in `package.json` dictate update behavior.
Intermediate Interview Questions
- Q: Explain the Node.js Event Loop.
- A: The Event Loop is what allows Node.js to perform non-blocking I/O operations despite being single-threaded. It offloads operations to the system kernel whenever possible. It consists of several phases: Timers (executes setTimeout/setInterval callbacks), Pending Callbacks, Idle/Prepare, Poll (retrieves new I/O events), Check (executes setImmediate callbacks), and Close Callbacks. It loops continuously as long as there are active tasks.
- Q: What is `process.nextTick()` and how does it differ from `setImmediate()`?
- A: `process.nextTick()` adds a callback to the 'next tick queue', which is processed *before* the Event Loop continues to the next phase, pausing all I/O. `setImmediate()` places a callback in the Check phase of the Event Loop, executing *after* the current Poll phase completes. Use `nextTick` for recursive/synchronous-looking code, but be careful not to starve the event loop.
- Q: What are Streams in Node.js?
- A: Streams are objects that let you read data from a source or write data to a destination in continuous, chunked fashion. Instead of loading an entire massive file into RAM (which crashes the server), streams process data piece by piece. The four types of streams are Readable, Writable, Duplex (both read/write), and Transform (modify data as it is written and read).
- Q: Explain the Buffer class.
- A: The `Buffer` class provides a way to handle raw binary data outside the V8 engine heap memory. Because raw JavaScript strings are Unicode, they aren't meant for binary data (like images or TCP streams). Buffers allocate a fixed amount of raw memory on the system to efficiently process streams of binary data.
- Q: What is the cluster module?
- A: Node.js runs in a single thread, utilizing only one CPU core. The `cluster` module allows you to create child processes (workers) that run simultaneously and share the same server port. This allows a Node.js application to take full advantage of multi-core systems, effectively multiplying processing power.
- Q: How do child processes work in Node.js?
- A: The `child_process` module provides the ability to spawn new processes. `spawn` launches a new process with a stream interface. `exec` runs a command in a shell and buffers the output. `fork` is a special case of `spawn` specifically used to spawn new Node.js processes, establishing an IPC (Inter-Process Communication) channel to send messages between parent and child.
- Q: What is CORS and how do you handle it in Node.js?
- A: Cross-Origin Resource Sharing (CORS) is a browser security feature that blocks HTTP requests made from a different domain, protocol, or port. In an Express app, you handle this using the `cors` middleware package. It injects `Access-Control-Allow-Origin` and related HTTP headers into responses, instructing the browser to permit the request.
- Q: How does JSON Web Token (JWT) authentication work?
- A: JWT is a stateless authentication mechanism. Upon login, the server verifies credentials and signs a JSON payload containing user data using a secret key. This token is sent to the client. The client attaches this token in the `Authorization` header on subsequent requests. The server verifies the signature locally without querying the database, ensuring scalability.
- Q: What are WebSockets and how do they differ from HTTP?
- A: HTTP is unidirectional (client requests, server responds) and stateless. WebSockets provide a full-duplex, persistent, bidirectional communication channel over a single TCP connection. Once the handshake is established, both client and server can push real-time data to each other instantly. Libraries like `Socket.io` implement WebSockets in Node.js.
- Q: How do you handle unhandled promise rejections or uncaught exceptions in Node?
- A: Unhandled exceptions crash the Node process. You can listen for the `uncaughtException` event on the `process` object. However, the application state might be corrupted, so best practice is to log the error and `process.exit(1)`. For promises, listen to the `unhandledRejection` event. In modern Node, unhandled promise rejections will also crash the process.
- Q: What is the difference between encryption and hashing?
- A: Hashing (e.g., `bcrypt`, `SHA-256`) is a one-way mathematical function. It converts data into a fixed-length string, and it cannot be reversed. It's used for storing passwords safely. Encryption (e.g., `AES-256`) is two-way. Data is encrypted using a key, and can be decrypted back to its original form using the same (or public/private) key.
- Q: Explain the concept of Rate Limiting.
- A: Rate limiting restricts the number of requests a client (based on IP or user ID) can make to an API within a specified timeframe. It protects the server from DDoS attacks, brute force login attempts, and resource exhaustion. In Express, it is commonly implemented using middleware like `express-rate-limit` backed by Redis.
- Q: What is the purpose of a reverse proxy like NGINX in front of Node.js?
- A: Node.js is great at executing logic but poor at serving static files or handling thousands of idle connections. A reverse proxy like NGINX sits in front, handles SSL termination, serves static assets efficiently, compresses payloads (Gzip), and load-balances requests across multiple Node.js instances.
- Q: How do you upload files in Express?
- A: Express cannot natively parse `multipart/form-data` requests, which are used for file uploads. You must use middleware like `multer` or `formidable`. `multer` parses the request, extracts the binary file data, saves it to disk (or memory), and attaches metadata to the `req.file` object.
- Q: What is the difference between `SQL` and `NoSQL` databases in the context of Node.js?
- A: SQL (PostgreSQL, MySQL) relies on strict schemas and relational tables. Use packages like `pg` or ORMs like `Prisma` or `Sequelize`. NoSQL (MongoDB) uses flexible, JSON-like document structures, which maps perfectly to JavaScript objects. Mongoose is the standard ODM for MongoDB in Node.js.
- Q: What is the `__dirname` variable?
- A: In CommonJS modules, `__dirname` is an automatically provided global-like variable that holds the absolute path of the directory containing the currently executing file. It is essential when constructing absolute file paths using `path.join(__dirname, 'file.txt')` to avoid relative path resolution bugs.
- Q: How does PM2 help in production?
- A: PM2 is a production process manager for Node.js. It ensures your application stays online indefinitely by automatically restarting it if it crashes. It also provides zero-downtime reloads, built-in load balancing (cluster mode), and comprehensive log management.
Advanced Interview Questions
- Q: Explain the libuv architecture and its role in Node.js.
- A: libuv is a multi-platform C library that provides Node.js with its non-blocking I/O and Event Loop. While V8 executes JS, libuv handles the OS-level operations (file systems, networking). For tasks that cannot be non-blocking at the OS level (like DNS lookups or File I/O), libuv utilizes a hidden 'Thread Pool' (default size of 4) to execute them asynchronously without blocking the main thread.
- Q: What is backpressure in Node.js Streams?
- A: Backpressure occurs when data is being read from a Readable stream faster than it can be processed or written to a Writable stream. If unchecked, the application will buffer the excess data in RAM until it crashes (OOM). Using `readableStream.pipe(writableStream)` automatically handles backpressure by pausing the readable stream until the writable stream's internal buffer drains.
- Q: How would you optimize a CPU-intensive task (like image processing) in Node.js?
- A: Because Node is single-threaded, a heavy CPU task will block the Event Loop, halting all incoming requests. To optimize, you must move the task off the main thread. You can use the `worker_threads` module to execute JS in parallel threads (sharing memory), or use `child_process.fork()` to spin up a separate Node process entirely.
- Q: Describe the security risks of Prototype Pollution in Node.js.
- A: Prototype Pollution occurs when a vulnerability allows an attacker to inject properties into the base `Object.prototype`. Since almost all JS objects inherit from `Object.prototype`, the attacker can alter the behavior of the entire application. It usually occurs through unsafe recursive merge operations (`merge(target, payload)` or `JSON.parse`). It can lead to DoS or Remote Code Execution.
- Q: What are the architectural differences between Monolithic and Microservices backends?
- A: A Monolith is a single unified codebase where all business logic, routing, and DB access are tightly coupled. It's easy to deploy but hard to scale. Microservices break the application into small, independent services (e.g., Auth Service, Payment Service) communicating via HTTP or message brokers (RabbitMQ, Kafka). They scale independently and allow polyglot programming, but introduce immense infrastructure complexity.
- Q: How does Node.js handle memory limits, and how can you increase them?
- A: By default, V8 sets a heap memory limit (approx 1.4GB on 64-bit systems). If an application exceeds this, it crashes with a 'heap out of memory' error. You can manually increase this limit when starting the node process by using the flag `--max-old-space-size=SIZE_IN_MB` (e.g., `node --max-old-space-size=4096 app.js`).
- Q: Explain the concept of 'Graceful Shutdown'.
- A: When a Node server receives a kill signal (SIGINT/SIGTERM), abruptly terminating drops active requests and corrupts DB transactions. Graceful shutdown means catching the signal, refusing new incoming requests, allowing existing requests to finish, safely closing database connections, and finally executing `process.exit(0)`.
- Q: What is GraphQL and how does it compare to REST?
- A: REST uses multiple endpoints returning fixed data structures, leading to over-fetching (getting too much data) or under-fetching (requiring N+1 requests). GraphQL is a query language utilizing a single endpoint. The client specifies exactly what fields it needs in the query, and the server resolves and returns precisely that data. It requires setting up schemas and resolvers.
- Q: How do you implement caching in a Node.js API?
- A: Caching prevents the server from querying the database for identical requests. In-memory caching (like `node-cache`) stores data in the Node process RAM, but is volatile and doesn't share state across a cluster. Distributed caching uses Redis. A middleware checks Redis for a cached response; if found, it returns it instantly. If not, it hits the DB, saves the result to Redis with a Time-To-Live (TTL), and responds.
- Q: Explain the Actor model vs message brokers (Kafka/RabbitMQ).
- A: Message brokers enable asynchronous communication between microservices by queuing messages. RabbitMQ is traditional message queuing (work queues, pub/sub). Kafka is a distributed event streaming platform built for massive throughput and event replay. The Actor model (less common in Node, standard in Erlang/Akka) treats 'Actors' as stateful entities that communicate purely by sending immutable messages to each other without shared locks.
- Q: What is a Memory Leak in Node.js and how do you trace it?
- A: A memory leak happens when objects are no longer needed but are still referenced by a global variable or active closure, preventing Garbage Collection. The RAM footprint grows until the server crashes. To trace it, run Node with the `--inspect` flag, connect Chrome DevTools, take Heap Snapshots during normal operation and under load, and compare them to find retaining paths.
- Q: How do you secure a Node.js application?
- A: 1) Use HTTPS. 2) Set secure HTTP headers using `Helmet`. 3) Prevent SQL/NoSQL injection using ORMs/parameterized queries. 4) Use Rate Limiting to prevent brute-force attacks. 5) Sanitize and validate all incoming inputs (`express-validator`). 6) Implement strict CORS. 7) Use secure cookie flags (HttpOnly, Secure, SameSite) or short-lived JWTs. 8) Audit dependencies via `npm audit`.
- Q: What is the N+1 Query Problem in ORMs?
- A: The N+1 problem occurs when an ORM queries the database for a list of items (1 query), and then executes an additional query for each item to fetch its associated nested data (N queries). This destroys database performance. The solution is using Eager Loading (e.g., `populate` in Mongoose, `include` in Prisma) or the DataLoader pattern (in GraphQL) to batch and resolve relationships in a single `IN` query.
- Q: Explain Server-Sent Events (SSE).
- A: SSE is a standard allowing servers to push real-time updates to web clients over a single, long-lived HTTP connection. Unlike WebSockets (which are bidirectional), SSE is strictly unidirectional (server to client). It's simpler to implement, works natively over HTTP/2, and is perfect for real-time dashboards or stock tickers where the client doesn't need to push data back constantly.
- Q: How do transaction mechanisms work in databases via Node?
- A: A transaction groups a series of operations into a single logical unit. It follows ACID principles. If any operation fails, the transaction is 'rolled back', undoing all partial changes. If all succeed, it is 'committed'. In Node, using tools like Prisma or raw SQL, you wrap queries inside a transaction callback to prevent partial data corruption (e.g., deducting money from user A, but failing to add it to user B).
- Q: What is the Event Loop lag and how do you monitor it?
- A: Event Loop lag is the delay between when a callback is scheduled to execute and when it actually executes. High lag means synchronous code is blocking the thread, degrading API response times. You monitor it using APM tools (Datadog, New Relic) or by writing a simple script that calls `setTimeout` and measures the difference between the expected execution time and the actual `Date.now()`.
Frequently Asked Questions
How many questions are covered in this guide?
This guide covers 50+ of the most frequently asked questions.
Are these questions suitable for beginners?
Yes, the guide is divided into beginner, intermediate, and advanced sections.
How often is this guide updated?
We update our interview questions quarterly to ensure they reflect current industry standards.
Should I memorize the answers?
No, it is better to understand the underlying concepts rather than memorizing answers word-for-word.
Are these questions asked at FAANG companies?
Yes, many of these questions are standard in interviews at top tech companies like Google, Amazon, and Meta.
Related Resources & Next Steps