DEV Community

Cover image for What's New in Node.js 22
Damilola Olatunji for AppSignal

Posted on • Originally published at blog.appsignal.com

What's New in Node.js 22

Node.js 22 has been released, offering a compelling upgrade for developers. It takes over the 'Current' release line, while v21 transitions into maintenance mode until its end-of-life in June.

This release delivers advances like a stabilized Watch mode, pattern matching support in the fs module, a default-enabled WebSocket client, and a new --run flag for script execution. It also offers some performance improvements and the usual V8 engine upgrade.

Let's dive in and explore all that Node.js v22 brings to the table!

Watch Mode is Stable

Watch Mode is stable

Node.js 18.11.0 introduced an incredibly useful --watch flag that allowed the
Node.js process to automatically restart any time an imported file was changed.

To use this functionality, you execute a command like this:

node --watch server.js
Enter fullscreen mode Exit fullscreen mode

The command would watch your server.js file and restart the process when it detected changes were made to the file or any of its imported modules.

You could also use the companion --watch-path flag (supported on macOS and Windows only) to specify the exact paths that should be monitored for changes, like this:

node --watch-path=./src --watch-path=./tests server.js
Enter fullscreen mode Exit fullscreen mode

However, because watch mode was marked as experimental, the below warning resulted whenever it was used:

(node:1710176) ExperimentalWarning: Watch mode is an experimental feature and might change at any time
Enter fullscreen mode Exit fullscreen mode

With the release of Node.js 22, this feature has been stabilized, so this warning no longer appears. While you could previously use a third-party tool like nodemon, this update removes the need for a dependency by adding it directly to Node.js core.

WebSocket Global Enabled by Default

In the previous Node 21 release, a built-in browser-compatible WebSocket client, as standardized by WHATWG, was added under the --experimental-websocket flag.

// index.js
const socket = new WebSocket("ws://localhost:8080");

socket.addEventListener("open", (event) => {
  socket.send("Hello Server!");
});

socket.addEventListener("message", (event) => {
  console.log("Message from server ", event.data);
});
Enter fullscreen mode Exit fullscreen mode

To use it, you had to run:

node --experimental-websocket index.js
Enter fullscreen mode Exit fullscreen mode

In Node.js 22, you no longer need to use the --experimental-websocket flag as the WebSocket global is now enabled by default. This means you can now open bidirectional communication channels between client and server without installing external dependencies.

Support for Running package.json Scripts

This release introduces an experimental --run flag, which provides a faster alternative to npm run for executing scripts defined in package.json files. Assuming you have a test script in your package.json, you can now execute it with:

node --run test
Enter fullscreen mode Exit fullscreen mode

On my machine, this runs twice as fast as npm run test:

hyperfine --warmup 3 'node --run test' 'npm test'
Enter fullscreen mode Exit fullscreen mode
Benchmark 1: node --run test
  Time (mean ± σ):     125.1 ms ±   4.4 ms    [User: 146.5 ms, System: 43.5 ms]
  Range (min … max):   116.7 ms … 134.7 ms    25 runs

Benchmark 2: npm run test
  Time (mean ± σ):     255.1 ms ±   8.5 ms    [User: 285.6 ms, System: 62.4 ms]
  Range (min … max):   245.5 ms … 275.9 ms    12 runs

Summary
  node --run test ran
    2.04 ± 0.10 times faster than npm run test
Enter fullscreen mode Exit fullscreen mode

Note that the goal of --run isn't to match all the behaviors of npm run, but to provide better performance in the most common cases. You can see a summary of its limitations in the Node docs.

Loading ES Modules with require()

To improve interoperability between ES Modules and the older CommonJS system, a new --experimental-require-module has been added to import ES Modules through require(). Here's how it works:

// hello.mjs is an ES Module
export default function () {
  console.log("hello world!");
}
Enter fullscreen mode Exit fullscreen mode
// index.js is a CommonJS Module
const hello = require("./hello.mjs").default;
hello();
Enter fullscreen mode Exit fullscreen mode

When you execute the index.js file with the --experimental-require-module:

node --experimental-require-module index.js
Enter fullscreen mode Exit fullscreen mode

You will observe the following output:

hello world!
(node:1738449) ExperimentalWarning: Support for loading ES Module in require() is an experimental feature and might change at any time
Enter fullscreen mode Exit fullscreen mode

For this to work, the following requirements must be met by the imported ES module:

  • It must be explicitly marked as an ES module through the .mjs extension, or with "type": "module" in the closest package.json file.
  • It must be fully synchronous, without a top-level await.

The goal is to eventually enable this behavior by default in a future release.

fs Module Supports Pattern Matching

Node.js 22 also introduces new APIs to the node:fs module for pattern matching. These are the glob and globSync methods that can be used for matching file paths based on the supplied glob pattern.

You can use it via node:fs or node:fs/promises:

import { glob } from "node:fs";

glob("**/*.js", (err, matches) => {
  if (err) throw err;
  console.log(matches);
});
Enter fullscreen mode Exit fullscreen mode
import { glob } from "node:fs/promises";

for await (const entry of glob("**/*.js")) console.log(entry);
Enter fullscreen mode Exit fullscreen mode

Note that this feature is currently marked as experimental, so you may see the following warning message when the API is used:

(node:1748923) ExperimentalWarning: glob is an experimental feature and might change at any time
Enter fullscreen mode Exit fullscreen mode

AbortSignal Performance Improvements

Creating AbortSignal instances is now significantly faster in Node.js 22. This class is used to notify observers when the abortController.abort() method is called. These enhancements directly benefit high-level APIs that utilize this class, such as fetch and the Node.js test runner.

Enhancements to Stream highWaterMark

The highWaterMark parameter, which controls the internal buffer size for streams, has been increased from 16KiB to 64KiB in Node.js 22. This change offers potential performance improvements across the board. However, the increase might lead to slightly higher memory consumption. For memory-sensitive applications, explicitly setting the buffer size with setDefaultHighWaterMark is recommended.

V8 Upgraded to v12.4

Node.js 22 ships with a customary upgrade to the V8 JavaScript engine, which brings several enhancements:

Should You Use Node.js 22 in Production?

Node.js 22, as an even-numbered release, is on track to become a Long-Term Support (LTS) version in October. This means guaranteed support and security updates until April 2027. However, until its LTS promotion, it will remain as the 'Current' release.

It's not necessary to upgrade to Node.js 22 in your production environment on day one. However, we advise that you explore the new features and improvements this version offers and its potential impact on your applications before performing the upgrade at a convenient time.

How to Upgrade to Node.js 22

Ready to experience the latest features in Node.js 22? Here's how to upgrade:

Direct Download

  • Visit the official Node.js download page
  • Choose the installer that matches your operating system and architecture, and install it as you normally would.

Node.js Download Page

Node.js Version Manager (Recommended)

For greater flexibility in managing multiple versions of Node.js simultaneously, consider a version management tool like Volta:

Volta

  • Install the Volta CLI (refer to the Volta documentation).
  • Use the following command to install or upgrade to Node.js 22:
volta install node@22
Enter fullscreen mode Exit fullscreen mode

This output confirms the installation is successful:

success: installed and set node@22.0.0 (with npm@10.5.1) as default
Enter fullscreen mode Exit fullscreen mode

Wrapping Up

Node.js v22 introduces numerous improvements in tooling, language features, standard library additions, and performance optimizations. These enhancements further solidify its position as the premier JavaScript runtime for modern web development.

For a complete breakdown of bug fixes, new features, and other changes, refer to the official Node.js v22 release notes.

If you're interested in getting involved with its development, explore Node's open issues and the Node contribution guidelines on GitHub.

Thanks for reading!

P.S. If you liked this post, subscribe to our JavaScript Sorcery list for a monthly deep dive into more magical JavaScript tips and tricks.

P.P.S. If you need an APM for your Node.js app, go and check out the AppSignal APM for Node.js.

Top comments (0)