Top 100 Node.js Interview Questions

An essential guide for backend developers. Covering the event loop, modules, Express.js, and more.

This guide provides a curated list of common Node.js interview questions to help you prepare for your next backend or full-stack developer role. Master these concepts, along with our guides on JavaScript and Git, to demonstrate your expertise in modern web development.

Last Updated: Aug 28, 2025

Table of Contents

Core Concepts & Architecture

1. What is Node.js?

Node.js is an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser. It's known for its non-blocking, event-driven architecture, which makes it efficient for building scalable network applications. You can learn more from the official Node.js website.

2. What is the event loop in Node.js?

The event loop is the core mechanism that allows Node.js to perform non-blocking I/O operations. It offloads operations to the system kernel whenever possible and processes events and callbacks from a queue when the call stack is empty. This enables Node.js to handle many concurrent connections efficiently without creating multiple threads.

A diagram of the Node.js event loop showing the call stack, callback queue, and different phases like timers, I/O, and check.

3. What is the difference between blocking and non-blocking I/O?

  • Blocking I/O: The execution of additional JavaScript is blocked until the I/O operation completes.
  • Non-blocking I/O: The I/O operation is offloaded to the system kernel, and the JavaScript execution continues. A callback is invoked when the operation is complete.

4. What is the `process` object in Node.js?

The `process` object is a global object that provides information about, and control over, the current Node.js process. It can be used to access environment variables, command-line arguments, and manage the process lifecycle.

5. What is the purpose of the `Buffer` class?

The `Buffer` class is used to handle binary data directly. It provides a way to work with streams of binary data, which is common in network protocols, file system operations, and other I/O-related tasks.

6. What is the difference between `setImmediate()` and `setTimeout()`?

`setImmediate()` executes a callback in the "check" phase of the event loop, immediately after I/O events. `setTimeout()` schedules a callback to be run after a minimum threshold in milliseconds, during the "timers" phase.

7. What is the difference between `process.nextTick()` and `setImmediate()`?

`process.nextTick()` executes a callback at the end of the current operation, before the event loop continues. `setImmediate()` executes a callback in the next iteration of the event loop.

8. What is the purpose of the `global` object?

The `global` object in Node.js is similar to the `window` object in browsers. It contains global variables and functions available throughout the application, such as `setTimeout`, `console`, and `process`.

9. What is the V8 engine?

V8 is Google's open-source JavaScript engine written in C++ that compiles JavaScript to native machine code. Node.js uses V8 to execute JavaScript code, which makes it fast and efficient.

10. What is the purpose of the `__dirname` and `__filename` variables?

`__dirname` returns the directory name of the current module. `__filename` returns the filename of the current module. Both are useful for resolving file paths relative to the current module.

Modules & NPM

11. What is the difference between `require` and `import`?

  • `require`: Part of the CommonJS module system, synchronous, can be called anywhere.
  • `import`: Part of the ES Modules (ESM) standard, asynchronous, must be used at the top level.

12. What is the difference between `module.exports` and `exports`?

`exports` is a reference to `module.exports`. You can add properties to `exports`, but reassigning `exports` will break the reference. `module.exports` is what is actually returned by `require()`.

13. What is `package.json`?

The `package.json` file is the manifest for a Node.js project. It contains metadata about the project, such as its name, version, and dependencies. It's essential for managing project dependencies with npm.

14. What is `package-lock.json`?

`package-lock.json` records the exact version of every dependency installed for a project. This ensures that every installation results in the exact same file structure in `node_modules`, making builds more reliable and reproducible.

15. What is the difference between `npm install` and `npm ci`?

  • `npm install`: Installs dependencies based on `package.json` and may update `package-lock.json`.
  • `npm ci`: Installs dependencies exactly as specified in `package-lock.json`, ensuring reproducible builds. It's faster and recommended for CI/CD environments.

16. What are the different types of npm dependencies?

  • dependencies: Packages required for your application to run in production
  • devDependencies: Packages needed only for development and testing
  • peerDependencies: Packages that expect the host to provide a specific version
  • optionalDependencies: Packages that are optional and won't break installation if they fail
  • bundledDependencies: Packages to be bundled when publishing your package

17. What is npx and how is it different from npm?

npx is a tool that comes with npm 5.2+ that allows you to execute Node packages without installing them globally. It downloads the package, runs it, and then removes it, making it useful for one-time use commands.

18. What is the purpose of the `node_modules` folder?

The `node_modules` folder is where npm installs all the dependencies for a project. Each dependency and its own dependencies are stored in a hierarchical structure.

19. How can you create a custom module in Node.js?

You can create a custom module by creating a JavaScript file and using `module.exports` or `exports` to expose functions, objects, or values that can be imported in other files using `require()`.

20. What are circular dependencies and how does Node.js handle them?

Circular dependencies occur when two modules require each other. Node.js handles this by returning an incomplete version of the module that's still being loaded, which can lead to unexpected behavior if not handled carefully.

Asynchronous Programming & Event Loop

21. What are callbacks in Node.js?

A callback is a function passed as an argument to another function, which is then invoked inside the outer function to complete some kind of routine or action. Callbacks are a fundamental part of asynchronous programming in Node.js.

22. What is "callback hell"?

"Callback hell" refers to heavily nested callbacks, which can become difficult to read and maintain. This is often solved by using Promises or `async/await`.

23. What are Promises?

A Promise is an object representing the eventual completion or failure of an asynchronous operation. It allows you to write asynchronous code in a more synchronous-like manner, avoiding callback hell.

24. What is `async/await`?

`async/await` is syntactic sugar built on top of Promises that makes asynchronous code even more readable and easier to reason about. An `async` function always returns a Promise, and `await` pauses the execution until a Promise is resolved.

25. What is the Event Emitter?

The Event Emitter is a core concept in Node.js that facilitates communication between objects. Many of Node's built-in modules inherit from `EventEmitter`. It allows objects to emit named events that cause registered listeners to be called.

26. How do you handle unhandled Promise rejections?

You can handle unhandled Promise rejections by listening to the `unhandledRejection` event on the process object:

process.on('unhandledRejection', (reason, promise) => {
  console.log('Unhandled Rejection at:', promise, 'reason:', reason);
});

27. What is the difference between `Promise.all()` and `Promise.allSettled()`?

`Promise.all()` resolves when all promises resolve or rejects when any promise rejects. `Promise.allSettled()` waits for all promises to settle (either resolve or reject) and returns an array of results for each promise.

28. What is the purpose of `util.promisify()`?

`util.promisify()` is a utility function that converts a callback-based function to a Promise-based one, making it easier to work with async/await syntax.

29. How can you execute multiple asynchronous operations in parallel?

You can use `Promise.all()` to execute multiple asynchronous operations in parallel and wait for all of them to complete.

30. What is the purpose of `async_hooks` module?

The `async_hooks` module provides an API to track the lifetime of asynchronous resources in Node.js, which is useful for creating asynchronous context propagation and monitoring.

Streams & Buffers

31. What are Streams in Node.js?

Streams are objects that let you read data from a source or write data to a destination in a continuous fashion. There are four types of streams: Readable, Writable, Duplex, and Transform. They are efficient for handling large amounts of data, like reading or writing large files.

32. What are the different types of streams?

  • Readable: Streams from which data can be read
  • Writable: Streams to which data can be written
  • Duplex: Streams that are both Readable and Writable
  • Transform: Duplex streams that can modify or transform the data as it is written and read

33. What is backpressure in streams?

Backpressure occurs when the data buffer is full and the source is producing data faster than the consumer can process it. Node.js streams handle backpressure automatically by pausing the readable stream when the writable stream's buffer is full.

34. What is the purpose of the `pipe()` method?

The `pipe()` method is used to connect a readable stream to a writable stream, automatically managing backpressure so that the destination stream is not overwhelmed by a faster readable stream.

35. What is the difference between flowing and paused modes for readable streams?

  • Flowing mode: Data is automatically read from the underlying system and provided to an application as quickly as possible
  • Paused mode: The `stream.read()` method must be called explicitly to read chunks of data from the stream

36. How do you create a custom transform stream?

You can create a custom transform stream by extending the `Transform` class and implementing the `_transform` method:

const { Transform } = require('stream');

class MyTransform extends Transform {
  _transform(chunk, encoding, callback) {
    // Transform the chunk
    this.push(transformedChunk);
    callback();
  }
}

37. What is the purpose of the `Buffer` class?

The `Buffer` class is used to handle binary data directly. It provides a way to work with streams of binary data, which is common in network protocols, file system operations, and other I/O-related tasks.

38. How do you convert a Buffer to a JSON string?

You can convert a Buffer to a JSON string using the `toJSON()` method:

const buf = Buffer.from('hello');
const json = JSON.stringify(buf.toJSON());

39. What is the difference between `Buffer.alloc()` and `Buffer.allocUnsafe()`?

`Buffer.alloc()` creates a new Buffer filled with zeros, which is safe but slightly slower. `Buffer.allocUnsafe()` creates a new Buffer without initializing the memory, which is faster but may contain sensitive data from previous allocations.

40. How do you handle large files efficiently in Node.js?

To handle large files efficiently, use streams instead of reading the entire file into memory. This allows you to process the file in chunks, reducing memory usage.

Express.js & Middleware

41. What is Express.js?

Express.js is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It simplifies the process of building web applications with Node.js.

42. What is middleware in Express.js?

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 code, make changes to the request and response objects, end the cycle, or call the next middleware.

43. What is the purpose of `app.use()` in Express?

`app.use()` is used to mount middleware functions at a specified path. When a path is specified, the middleware function is executed for any type of HTTP request to that path.

44. How do you handle routes in Express?

Routes are handled using methods on the Express app object that correspond to HTTP methods, such as `app.get()`, `app.post()`, `app.put()`, and `app.delete()`. These methods specify a callback function that is called when the application receives a request to the specified route.

45. What is the purpose of the `next` function in Express middleware?

The `next` function is a callback that passes control to the next middleware function in the stack. If `next()` is not called, the request-response cycle will hang, and the client will not receive a response.

46. How do you handle errors in Express?

Errors in Express can be handled using error-handling middleware functions that have four arguments: `(err, req, res, next)`. These middleware functions are defined last, after other `app.use()` and route calls.

47. What is the purpose of `express.Router()`?

`express.Router()` is used to create modular, mountable route handlers. A Router instance is a complete middleware and routing system, often referred to as a "mini-app".

48. How do you serve static files in Express?

Static files can be served using the `express.static` middleware function:

app.use(express.static('public'));

49. What is the difference between `app.get()` and `app.use()`?

`app.get()` handles only GET requests for a specific route, while `app.use()` handles all HTTP methods for a specific path and is typically used for middleware.

50. How do you get query parameters in Express?

Query parameters can be accessed through the `req.query` object:

app.get('/search', (req, res) => {
  const query = req.query.q;
  // Process the query
});

Error Handling & Debugging

51. What are the different types of errors in Node.js?

  • Standard JavaScript errors: SyntaxError, ReferenceError, TypeError, etc.
  • System errors: Errors that occur from the underlying operating system
  • User-specified errors: Custom errors created by the application
  • Assertion errors: Errors thrown by the `assert` module

52. What is the difference between `throw`, `callback(error)`, and `Promise.reject()`?

  • `throw`: Used to throw an exception synchronously
  • `callback(error)`: Used to pass an error to a callback function in asynchronous operations
  • `Promise.reject()`: Used to create a rejected promise in promise-based asynchronous operations

53. How do you handle uncaught exceptions in Node.js?

Uncaught exceptions can be handled using the `uncaughtException` event on the process object:

process.on('uncaughtException', (error) => {
  console.error('Uncaught Exception:', error);
  // Perform cleanup and exit process
  process.exit(1);
});

54. What is the purpose of the `domain` module?

The `domain` module (deprecated) was used to handle multiple different I/O operations as a single group. It provided a way to handle errors that occurred anywhere in the group of operations.

55. How do you create custom error types in Node.js?

Custom error types can be created by extending the `Error` class:

class CustomError extends Error {
  constructor(message) {
    super(message);
    this.name = 'CustomError';
  }
}

56. What is the difference between operational errors and programmer errors?

  • Operational errors: Represent runtime problems that should be handled gracefully (e.g., failed to connect to database)
  • Programmer errors: Represent bugs in the program (e.g., trying to read property of undefined)

57. How do you handle errors in asynchronous code?

Errors in asynchronous code can be handled using:

  • Callbacks: Pass error as the first argument
  • Promises: Use `.catch()` method or try/catch with async/await
  • Async/await: Use try/catch blocks

58. What is the purpose of the `assert` module?

The `assert` module provides a set of assertion functions for verifying invariants. If the condition is not met, an `AssertionError` is thrown, which is useful for testing.

59. How do you handle errors in Express middleware?

Errors in Express middleware can be handled by creating error-handling middleware with four arguments:

app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

60. What is the purpose of the `error` event on EventEmitter?

The `error` event is emitted when an error occurs within an EventEmitter. If no listener is registered for the `error` event, the error will be thrown, which may crash the Node.js process.

Testing & Best Practices

61. What are some popular testing frameworks for Node.js?

  • Jest
  • Mocha
  • Jasmine
  • Ava
  • Tap

62. What is the purpose of assertion libraries like Chai?

Assertion libraries like Chai provide expressive ways to write tests and make assertions about your code. They offer different styles (should, expect, assert) for writing assertions.

63. How do you debug a Node.js application?

Node.js applications can be debugged using:

  • The built-in debugger with `node inspect` command
  • Chrome DevTools with `--inspect` flag
  • VS Code's built-in debugger
  • Third-party tools like ndb

64. What is the purpose of the `--inspect` flag?

The `--inspect` flag enables the Node.js inspector, which allows debugging using the Chrome DevTools or other compatible debuggers.

65. How do you mock dependencies in tests?

Dependencies can be mocked using libraries like Sinon, Jest's built-in mocking capabilities, or by using proxyquire to override require calls.

66. What is the purpose of the `console` object?

The `console` object provides simple debugging capabilities, including methods like `console.log()`, `console.error()`, and `console.trace()` for outputting information to stdout or stderr.

67. How do you profile a Node.js application?

Node.js applications can be profiled using:

  • The `--prof` flag to generate a v8.log file
  • The `--cpu-prof` flag to generate CPU profiles
  • Third-party tools like clinic.js or 0x

68. What is the purpose of the `util.inspect()` method?

The `util.inspect()` method returns a string representation of an object that is useful for debugging. It can show hidden properties and has options to control the depth of inspection.

69. How do you write unit tests for asynchronous code?

Asynchronous code can be tested using:

  • Callbacks: Call the done function when complete
  • Promises: Return the promise from the test
  • Async/await: Use async test functions

70. What is the purpose of code coverage tools?

Code coverage tools measure how much of your code is executed during tests. Popular tools include Istanbul (nyc), Jest's built-in coverage, and c8.

Performance, Scaling & Child Processes

71. How does Node.js handle scalability?

Node.js handles scalability through its event-driven, non-blocking I/O model which allows it to handle many concurrent connections with a single thread. For CPU-intensive tasks, it can use child processes or worker threads to leverage multiple CPU cores.

72. What is the Cluster module?

The Cluster module allows you to create child processes (workers) that share the same server port. This enables a Node.js application to take advantage of multi-core systems by running multiple instances of the application.

73. What is the difference between `child_process` and `cluster`?

`child_process` is used to create any child process to run system commands or other programs. `cluster` is specifically designed to create multiple instances of a Node.js application that share the same port.

74. What are Worker Threads?

Worker Threads allow running JavaScript in parallel using separate threads. Unlike child processes, worker threads can share memory through SharedArrayBuffer and are lighter weight for CPU-intensive tasks.

75. How do you monitor the performance of a Node.js application?

Node.js application performance can be monitored using:

  • Built-in modules like `perf_hooks`
  • APM tools like New Relic, AppDynamics, or Datadog
  • Custom metrics with Prometheus and Grafana
  • Logging and tracing with tools like Jaeger or Zipkin

76. What is the purpose of the `perf_hooks` module?

The `perf_hooks` module provides an implementation of the W3C Performance Timeline specification to measure the performance of Node.js applications.

77. How do you optimize the performance of a Node.js application?

Node.js application performance can be optimized by:

  • Using streams for large data processing
  • Implementing caching strategies
  • Optimizing database queries
  • Using compression middleware
  • Clustering for multi-core utilization

78. What is the purpose of the `v8` module?

The `v8` module exposes APIs that are specific to the version of V8 built into the Node.js binary. It can be used to get heap statistics and control V8 options.

79. How do you handle memory leaks in Node.js?

Memory leaks can be handled by:

  • Using tools like heapdump or the Chrome DevTools Memory tab
  • Monitoring memory usage with `process.memoryUsage()`
  • Avoiding global variables
  • Clearing intervals and timeouts
  • Properly closing event listeners and streams

80. What is the purpose of the `--max-old-space-size` flag?

The `--max-old-space-size` flag sets the maximum size (in megabytes) of the old memory region in V8. This can be used to increase the memory limit for Node.js applications.

Security Best Practices

81. What are some common security vulnerabilities in Node.js applications?

  • Injection attacks (SQL, NoSQL, Command)
  • Cross-Site Scripting (XSS)
  • Cross-Site Request Forgery (CSRF)
  • Authentication and Session Management flaws
  • Insecure dependencies
  • Security misconfigurations

82. How do you prevent SQL injection in Node.js?

SQL injection can be prevented by:

  • Using parameterized queries or prepared statements
  • Using ORMs that handle sanitization
  • Validating and sanitizing user input
  • Using libraries like `sqlstring` for MySQL

83. What is the purpose of the `helmet` middleware?

Helmet.js is a collection of middleware functions that help secure Express apps by setting various HTTP headers. It helps protect against common web vulnerabilities like XSS, clickjacking, etc.

84. How do you manage authentication in Node.js?

Authentication can be managed using:

  • Session-based authentication with `express-session`
  • Token-based authentication with JWT
  • OAuth with Passport.js
  • Third-party services like Auth0 or Firebase Auth

85. What is the purpose of the `bcrypt` library?

The `bcrypt` library is used to hash passwords securely. It implements the bcrypt password-hashing function, which is designed to be computationally expensive to prevent brute-force attacks.

86. How do you handle Cross-Origin Resource Sharing (CORS) in Node.js?

CORS can be handled using the `cors` middleware for Express:

const cors = require('cors');
app.use(cors());

87. What is the purpose of the `csurf` middleware?

The `csurf` middleware provides CSRF protection by generating and validating tokens. It requires session middleware to be initialized first.

88. How do you secure HTTP cookies in Express?

HTTP cookies can be secured by:

  • Setting the `secure` flag for HTTPS-only cookies
  • Setting the `httpOnly` flag to prevent client-side access
  • Setting the `sameSite` attribute to prevent CSRF
  • Using signed cookies with a secret

89. How do you check for vulnerable dependencies?

Vulnerable dependencies can be checked using:

  • `npm audit` command
  • Third-party tools like Snyk or Dependabot
  • CI/CD integration with vulnerability scanning

90. What is the purpose of rate limiting?

Rate limiting protects against brute-force attacks and DoS attacks by limiting the number of requests a client can make in a given time period. It can be implemented using middleware like `express-rate-limit`.

Ecosystem & Deployment

91. What is the difference between development and production environments?

  • Development: Debugging enabled, verbose logging, hot reloading
  • Production: Optimized for performance, minimal logging, environment-specific configuration

92. What is the purpose of the `NODE_ENV` environment variable?

The `NODE_ENV` environment variable is used to specify the environment in which the application is running (e.g., 'development', 'production', 'test'). Many libraries and frameworks use this to enable or disable certain features.

93. What are some popular Node.js frameworks?

  • Express.js - Web application framework
  • Nest.js - Progressive framework for building efficient applications
  • Koa.js - Next generation web framework by Express creators
  • Socket.io - Real-time communication framework
  • Hapi.js - Rich framework for building applications and services

94. What is the purpose of process managers like PM2?

Process managers like PM2 help to:

  • Keep applications alive forever
  • Reload applications without downtime
  • Manage application logging
  • Monitor runtime performance
  • Manage cluster mode

95. How do you deploy a Node.js application?

Node.js applications can be deployed using:

  • Traditional servers with process managers (PM2)
  • Containerization with Docker
  • Platform as a Service (PaaS) like Heroku, AWS Elastic Beanstalk
  • Serverless platforms like AWS Lambda
  • Kubernetes for container orchestration

96. What is the purpose of the `dotenv` package?

The `dotenv` package loads environment variables from a `.env` file into `process.env`. This is useful for keeping configuration separate from code, especially in development.

97. What are some popular database ORMs/ODMs for Node.js?

  • Sequelize - ORM for SQL databases
  • Mongoose - ODM for MongoDB
  • TypeORM - ORM that supports both SQL and NoSQL
  • Prisma - Next-generation ORM
  • Knex.js - SQL query builder

98. What is the purpose of the `nodemon` tool?

Nodemon is a utility that monitors for changes in your source code and automatically restarts your Node.js application. It's commonly used during development to improve productivity.

99. What is the LTS version of Node.js?

LTS (Long Term Support) versions of Node.js are versions that are supported with bug fixes and security updates for an extended period. They are recommended for production use.

100. What are some best practices for writing Node.js applications?

  • Use `async/await` for asynchronous code
  • Use a linter and code formatter
  • Handle errors properly
  • Use environment variables for configuration
  • Implement logging
  • Write tests for your code
  • Use a process manager like PM2 for production
  • Keep dependencies updated
  • Follow the principle of least privilege for security
  • Use appropriate design patterns
DevUtilityTool Logo

About the Author

This guide is curated by the team at DevUtilityTool, who are passionate about creating high-quality, accessible resources that help developers excel in their careers.