What Is New in Node.js 24?
| Category | Change |
|---|---|
| New Features | V8 13.6 -- Float16Array, explicit resource management (using/await using), RegExp.escape, Error.isError |
| New Features | URLPattern exposed as a global (no import needed) |
| New Features | AsyncLocalStorage default implementation switched to AsyncContextFrame |
| New Features | Permission Model flag simplified from --experimental-permission to --permission |
| New Features | WebAssembly Memory64 support |
| Improvements | npm upgraded to version 11 |
| Improvements | Undici 7 -- improved HTTP client performance and features |
| Improvements | Test runner: auto-waits for subtests to finish (breaking change) |
| Improvements | HTTP/2: session tracking and graceful server close |
| Deprecated | url.parse() -- runtime deprecation, use WHATWG URL API |
| Deprecated | SlowBuffer moved to end-of-life |
| Removed | tls.createSecurePair removed |
| Build | MSVC support dropped -- ClangCL now required on Windows |
Explicit Resource Management -- using and await using
Node.js 24 ships the TC39 Explicit Resource Management proposal natively via V8 13.6. The using and await using declarations automatically call a resource's [Symbol.dispose]() or [Symbol.asyncDispose]() method when the block exits -- regardless of whether it exits normally or via an exception.
// Synchronous resource -- auto-closes when block exits
{
using handle = openFileHandle('./data.csv');
const data = handle.read();
// handle[Symbol.dispose]() called automatically here
}
// Async variant for database connections, etc.
async function query() {
await using conn = await db.connect();
return conn.execute('SELECT 1');
// conn[Symbol.asyncDispose]() called automatically
}
This replaces the try/finally cleanup pattern. In practice it is most useful for file handles, database connections, locks, and any resource with a defined lifecycle. Node.js built-ins will add Symbol.dispose support incrementally in future releases.
New V8 13.6 JavaScript Features
Float16Array -- a new TypedArray for 16-bit floating-point numbers. Useful for machine learning inference (weights commonly stored as FP16), WebGPU interop, and memory-constrained numeric processing.
const weights = new Float16Array(1024); // half-precision floats
// Smaller memory footprint vs Float32Array
RegExp.escape(str) -- escapes a string so it can be safely inserted into a regex pattern without any character being interpreted as a quantifier or metacharacter.
const userInput = 'hello.world+test';
const pattern = new RegExp(RegExp.escape(userInput));
// No more manual replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
Error.isError(value) -- reliably checks whether a value is an Error object across realm boundaries (iframes, workers), where instanceof Error can return false for errors from other contexts.
URLPattern Now a Global
URLPattern is available in the global scope -- no import required. It provides a standard pattern matching system for URLs using the same syntax as the URL Pattern API in browsers. This is useful for routing, middleware, and any code that needs to match URL shapes without setting up a full router.
const pattern = new URLPattern({ pathname: '/api/:version/users/:id' });
const match = pattern.exec('https://example.com/api/v2/users/42');
console.log(match?.pathname.groups); // { version: 'v2', id: '42' }
AsyncLocalStorage and AsyncContextFrame
AsyncLocalStorage now uses AsyncContextFrame as its default backend instead of the older async hooks mechanism. This improves performance, reduces overhead on the async context propagation path, and resolves edge-case correctness bugs.
For most users this is transparent. If you built tooling on top of AsyncLocalStorage internals or async_hooks directly, test your code on Node.js 24 -- the observable behavior of AsyncLocalStorage.getStore() is unchanged, but internal hook invocation timing may differ.
Permission Model and Test Runner Changes
The Permission Model flag changes from --experimental-permission to --permission, signaling its readiness for broader use. The permission system lets you restrict what filesystem paths, child processes, and native addons a Node.js process can access at startup.
node --permission --allow-fs-read=/data --allow-fs-write=/tmp server.js
The test runner auto-waits for subtests -- a breaking change. Previously t.test() returned a Promise you could await. In v24 that promise is removed; subtests are tracked and awaited automatically. Code that explicitly awaited subtest results needs updating.
FAQ
Is Node.js 24 an LTS release?
It becomes an LTS release in October 2025. Until then it is the "Current" release. Production deployments should plan to adopt it when LTS status is granted and upgrade from Node.js 22 LTS.
Does the using keyword require TypeScript 5.2+?
Yes, TypeScript 5.2 added support for the Explicit Resource Management proposal. For Node.js 24, you can use using natively in JavaScript without TypeScript -- just ensure your tooling (ESLint, Babel) supports the syntax if it processes your source files.
Will my existing AsyncLocalStorage code break in v24?
The public API is unchanged. The internal backend switch to AsyncContextFrame is designed to be transparent. Edge cases around async_hooks that were previously masked may surface. Run your async context tests on v24 before deploying.
What does the Undici 7 upgrade change for fetch()?
Undici 7 improves HTTP client performance, adds better support for modern HTTP features, and tightens spec compliance. Most changes are internal improvements. If you use Undici directly (not just through fetch), check Undici's own changelog for breaking changes.
Can I still build Node.js 24 with Visual Studio on Windows?
MSVC is no longer supported as of Node.js 24. You need ClangCL (Clang with MSVC-compatible output), which is included in Visual Studio 2019+ via the "C++ Clang tools for Windows" component. Install it and point the build to ClangCL.