Skip to main content

Cloudsoft Zone Build, deploy and scale with practical guides to PHP, Node.js, React, DevOps and AI automation. Explore the guides

Cloudsoft Zone
Interview questionsJavaScriptNode.jsInterview preparation

Node.js interview questions and answers for Node.js 24 LTS

20 Node.js interview questions with model answers checked against the Node.js 24 docs: the event loop, nextTick versus setImmediate, streams, worker threads, the permission model, built-in test runner, TypeScript type stripping and graceful shutdown.

Cloudsoft Zone

Updated 9 min read

Rows of rack-mounted servers with status lights in a Wikimedia Foundation data centre
Photograph: Victorgrigas / CC BY-SA 3.0, via Wikimedia Commons
In this article

Node.js interviews focus on one idea more than any other: how a single JavaScript thread handles thousands of concurrent connections without blocking. Interviewers then check that you can apply it, with questions on streams, error handling, scaling across CPU cores and running services safely in production.

The platform has also changed a lot in the last two years. Node.js 24 is the Active LTS line, Node.js 26 is scheduled to become LTS on 28 October 2026, and Node.js 20 reached end of life on 30 April 2026. Features that used to need third-party packages, such as loading .env files, running tests, a permission model and running TypeScript files, are now built in and stable.

The 20 questions below are grouped by level. Model answers are checked against the Node.js 24 API documentation and the Node.js release schedule.

Ryan Dahl, the original author of Node.js, speaking at YUIConf 2010 in Sunnyvale, California
Ryan Dahl, who created Node.js, speaking at YUIConf 2010. Photo: David Calhoun, CC BY 2.0.

Release lines to know (October 2026)

LineStatusEnd of life
Node.js 22 "Jod"Maintenance LTS30 Apr 2027
Node.js 24 "Krypton"Active LTS; maintenance from 20 Oct 202630 Apr 2028
Node.js 26Current; LTS from 28 Oct 202630 Apr 2029

Production applications should run an LTS line. Even-numbered releases become LTS; odd-numbered ones do not.

Beginner questions

1. What is Node.js, and why is it good at I/O?

Node.js is a JavaScript runtime built on the V8 engine, with libuv providing the event loop and asynchronous I/O. Your JavaScript runs on one main thread, but network and file operations are handed to the operating system or a small thread pool. While they are in progress, the thread keeps serving other requests. This makes Node.js efficient for I/O-heavy work such as APIs, proxies and real-time services, and less suited to long CPU-bound calculations on the main thread.

2. What do package.json and the lockfile do?

package.json describes the project: name, scripts, dependencies with semver ranges, the module type and entry points. The lockfile (package-lock.json, pnpm-lock.yaml or yarn.lock) records the exact resolved version of every package, so every install produces the same tree. Commit the lockfile, and use npm ci (or the equivalent) in CI and production builds.

3. How does Node.js decide whether a file is CommonJS or an ES module?

.mjs files are ES modules and .cjs files are CommonJS. For .js files, the nearest package.json decides: "type": "module" means ES modules, "type": "commonjs" means CommonJS. If there is no type field, Node.js checks the file for ES module syntax. Since Node.js 24.15, require() of a synchronous ES module (one without top-level await) is no longer experimental.

4. How do you load configuration from a .env file?

Use the built-in flag: node --env-file=.env server.js. It is no longer experimental since Node.js 24.10. Values already present in the real environment take precedence over the file, and --env-file-if-exists does not fail when the file is missing. Never commit real .env files.

5. What is an error-first callback?

The older Node.js convention where a callback receives an error as its first argument and the result as the second: fs.readFile(path, (err, data) => { ... }). Most core modules now also offer promise APIs, such as node:fs/promises, which work with async/await.

Intermediate questions

6. Describe the phases of the Node.js event loop.

Each turn of the loop moves through these phases: timers (callbacks from setTimeout and setInterval), pending callbacks (some deferred system callbacks), idle, prepare (internal), poll (retrieve new I/O events and run their callbacks), check (setImmediate callbacks) and close callbacks (such as a socket's close event). Between callbacks, Node.js drains the process.nextTick queue and then the promise microtask queue.

7. process.nextTick, setImmediate or setTimeout(fn, 0)?

JavaScript
import { readFile } from 'node:fs';

readFile(import.meta.filename, () => {
  setTimeout(() => console.log('timeout'), 0);
  setImmediate(() => console.log('immediate'));
  process.nextTick(() => console.log('nextTick'));
  Promise.resolve().then(() => console.log('promise'));
});
// nextTick, promise, immediate, timeout

process.nextTick runs before anything else once the current operation finishes, even before promise callbacks. setImmediate runs in the check phase. Inside an I/O callback, setImmediate always runs before a zero-delay timer; in the main module the order of those two is not guaranteed. Prefer setImmediate or queueMicrotask; recursive nextTick calls can starve I/O.

8. What does "blocking the event loop" mean, and how do you avoid it?

Any long synchronous work, such as a large JSON.parse, a heavy loop, synchronous file calls like fs.readFileSync in a request handler, or a slow regular expression, stops every other request until it ends. Avoid it by using asynchronous APIs, splitting work into chunks, streaming large data and moving CPU-heavy tasks to worker threads or a separate service.

9. What are streams, and what is backpressure?

Streams process data piece by piece instead of loading it all into memory: readable, writable, duplex and transform streams. Backpressure is the signal a slow destination sends to a fast source to pause. stream.pipeline() handles backpressure, forwards errors and cleans up every stream, so prefer it to chaining .pipe().

JavaScript
import { createReadStream, createWriteStream } from 'node:fs';
import { createGzip } from 'node:zlib';
import { pipeline } from 'node:stream/promises';

await pipeline(
  createReadStream('access.log'),
  createGzip(),
  createWriteStream('access.log.gz'),
);

10. What is EventEmitter?

The class behind many core APIs (servers, streams, processes). Objects emit named events and listeners subscribe with on or once. Listeners run synchronously in registration order. An 'error' event with no listener throws and can crash the process, so always handle errors on emitters you create.

11. What happens with an unhandled promise rejection?

Since Node.js 15, the default --unhandled-rejections mode is throw: an unhandled rejection is raised as an uncaught exception and, without a handler, the process exits. Handle errors where they occur; use process.on('uncaughtException') and 'unhandledRejection' only to log and shut down cleanly, not to keep running in an unknown state.

12. worker_threads, cluster or child_process?

  • worker_threads: threads in the same process, each with its own event loop and V8 isolate. Use them for CPU-heavy JavaScript; they can share memory with SharedArrayBuffer.
  • cluster: forks several Node.js processes that share a server port, to use all CPU cores for a web server. Many teams use a process manager or container orchestration for this instead.
  • child_process: runs other programs (or Node.js scripts) as separate processes with spawn, exec or fork.

13. What is the exports field in package.json?

It defines a package's public entry points and blocks imports of anything not listed. It also supports conditional exports, such as different files for import and require. Adding exports to an existing package can be a breaking change because deep imports stop working.

Advanced questions

14. How does the Node.js permission model work?

Starting a process with --permission restricts file system access, spawning processes, worker threads, native add-ons, WASI and the inspector unless you grant them, for example node --permission --allow-fs-read=/srv/app --allow-fs-write=/srv/app/tmp /srv/app/server.js. Denied operations throw ERR_ACCESS_DENIED, and --permission-audit reports violations without blocking them, which helps you discover the grants an application needs. The permission model is stable in Node.js 24. It limits damage from a compromised dependency, but the documentation states it does not protect against malicious code, so it complements other controls rather than replacing them.

15. Can Node.js run TypeScript directly?

Yes, through type stripping: Node.js removes type annotations and runs the result. It is enabled by default since 23.6 and marked stable since 24.12. Only "erasable" syntax is supported; features that need code generation, such as enum declarations and namespaces with runtime code, require --experimental-transform-types or a full compiler. Type stripping does not type-check, so keep running tsc --noEmit in CI, and consider the erasableSyntaxOnly compiler option.

16. How do you write tests without a framework?

Use the stable built-in test runner, node:test, with node:assert. Run tests with node --test. It supports subtests, hooks, mocking, watch mode and coverage reporting.

JavaScript
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { slugify } from './slugify.js';

test('slugify lower-cases and joins words', () => {
  assert.equal(slugify('Hello Node World'), 'hello-node-world');
});

17. How do you shut a server down gracefully?

Listen for SIGTERM (sent by Docker, Kubernetes and most process managers), stop accepting new connections with server.close(), let in-flight requests finish, close database pools and queues, then exit. Add a timeout that forces exit if cleanup hangs.

JavaScript
process.on('SIGTERM', () => {
  server.close(async () => {
    await db.end();
    process.exit(0);
  });
  setTimeout(() => process.exit(1), 10_000).unref();
});

18. What is AsyncLocalStorage used for?

It stores context that follows an asynchronous call chain, such as a request ID or the current user, without passing it through every function. Logging libraries use it to attach the request ID to every log line for that request. It lives in node:async_hooks and is stable.

19. How would you find a memory leak in a Node.js service?

Confirm the trend with metrics (heap used growing across garbage collections). Start the process with --inspect and take heap snapshots in Chrome DevTools a few minutes apart, then compare which objects are growing. Common causes are unbounded in-memory caches, listeners added on every request and closures holding large objects. --heapsnapshot-near-heap-limit can capture a snapshot automatically before a crash.

20. What security practices do you follow for a Node.js API?

  • Run a supported LTS version and apply security releases promptly.
  • Validate every input against a schema and set request body size limits.
  • Use parameterised queries; never build SQL with string concatenation.
  • Set security headers, rate-limit authentication routes, and keep secrets in environment variables or a secret manager.
  • Audit dependencies (npm audit or your scanner of choice), keep the lockfile committed and review new packages before adding them.
  • Do not run the process as root, and consider the permission model.
Developer screen with highlighted JavaScript functions and HTML markup in a code editor
Run every snippet on Node.js 24 LTS before your interview. Photo: Martin Vorel, CC BY-SA 4.0.

Practice plan

  1. Install Node.js 24 LTS and run every snippet above.
  2. Build a small HTTP API that streams a file, uses --env-file, has node:test tests and shuts down gracefully.
  3. Block the event loop on purpose with a long loop, measure the effect on another request, then move the work to a worker thread.
  4. Read the event loop guide on nodejs.org once more the day before the interview.

Next steps

Node.js interviews often begin with JavaScript fundamentals, so review our JavaScript interview questions too, and the MySQL set if the role involves a relational database.

Frequently asked questions

  • Which Node.js version should I use for interview practice?

    Node.js 24, the Active LTS line. Node.js 26 becomes LTS on 28 October 2026, and Node.js 20 reached end of life on 30 April 2026.

  • Does Node.js run TypeScript files without a build step?

    Yes, through type stripping, which is stable since Node.js 24.12. Only erasable syntax works without extra flags, and types are not checked, so keep running tsc --noEmit.

  • What is the difference between process.nextTick and setImmediate?

    process.nextTick callbacks run as soon as the current operation finishes, before promise callbacks. setImmediate callbacks run in the check phase of the event loop, after I/O polling.

  • Do I still need dotenv?

    Often not. node --env-file=.env is built in and no longer experimental since Node.js 24.10.

Advertise on CloudSoftZone

Your next customer could start right here.

Introduce your tool, product or business to readers exploring technology.

Advertise with us

Explore placements and request a private quote

Sources

  1. Node.js release schedule — OpenJS Foundation
  2. The Node.js event loop — OpenJS Foundation
  3. Modules: TypeScript — OpenJS Foundation
  4. Permissions — OpenJS Foundation
  5. Modules: CommonJS (require of ES modules) — OpenJS Foundation
  6. Command-line options — OpenJS Foundation
  7. Test runner — OpenJS Foundation

Written with substantial AI assistance. Facts checked against cited sources. Editorial policy.

Comments

No comments yet. Be the first to join the conversation.

Leave a comment

Every comment is read by a moderator before it appears. Your email address is never published; it is used only to contact you about this comment.

Never published. Used only to contact you about this comment.

Loading the security check…

Comments are moderated before publication.