javascript

What's New in Node.js 22

Damilola Olatunji

Damilola Olatunji on

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:

shell
node --watch server.js

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:

shell
node --watch-path=./src --watch-path=./tests server.js

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

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

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.

javascript
// 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); });

To use it, you had to run:

shell
node --experimental-websocket index.js

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:

shell
node --run test

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

shell
hyperfine --warmup 3 'node --run test' 'npm test'
text
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

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:

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

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

shell
node --experimental-require-module index.js

You will observe the following output:

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

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:

javascript
import { glob } from "node:fs"; glob("**/*.js", (err, matches) => { if (err) throw err; console.log(matches); });
javascript
import { glob } from "node:fs/promises"; for await (const entry of glob("**/*.js")) console.log(entry);

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

text
(node:1748923) ExperimentalWarning: glob is an experimental feature and might change at any time

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

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:
shell
volta install node@22

This output confirms the installation is successful:

text
success: installed and set node@22.0.0 (with npm@10.5.1) as default

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.

Damilola Olatunji

Damilola Olatunji

Damilola is a freelance technical writer and software developer based in Lagos, Nigeria. He specializes in JavaScript and Node.js, and aims to deliver concise and practical articles for developers. When not writing or coding, he enjoys reading, playing games, and traveling.

All articles by Damilola Olatunji

Become our next author!

Find out more

AppSignal monitors your apps

AppSignal provides insights for Ruby, Rails, Elixir, Phoenix, Node.js, Express and many other frameworks and libraries. We are located in beautiful Amsterdam. We love stroopwafels. If you do too, let us know. We might send you some!

Discover AppSignal
AppSignal monitors your apps