Migrating from Node.js 22 LTS to Node.js 24 LTS
The Node.js Project
With the release of Node.js 24.11.0, the Node.js 24 release line has entered Long-Term Support (LTS) and will continue to receive updates through to the end of April 2028.
If you are migrating from Node.js 22 LTS, this article summarizes the breaking changes that came in Node.js 23.0.0 and Node.js 24.0.0.
Platform support
Node.js no longer provides pre-built binaries for:
- 32-bit Windows (x86) as of Node.js 23.0.0.
- 32-bit Linux on armv7 as of Node.js 24.0.0.
Pre-built binaries for macOS now require a minimum of macOS 13.5.
Pre-built binaries for Linux on arm64, ppc64le, s390x and x64 continue to be compatible with glibc 2.28 and above (no change from Node.js 22).
Please refer to additional notes if you are building Node.js from source.
Assistance with updating source-code
For some breaking changes, and adoption of some new features, Node.js provided migrations are available to aid source-code modifications.
Breaking changes
Deprecated APIs
Removed APIs
CipherandDecipherclasses fromnode:crypto.dirent.path.fs.truncate()using a file descriptor.OutgoingMessage.prototype._headers,OutgoingMessage.prototype._headerNamesfrom thenode:httpmodule.- HTTP/2 priority signaling.
net._setSimultaneousAccepts().process.assert().timers.active().timers.enroll().timers.unenroll().timers._unrefActive().tls.createSecurePair().tls.SecurePair.tlsServer.prototype.setOptions().util.isBoolean().util.isBuffer().util.isDate().util.isError().util.isFunction().util.isNull().util.isNullOrUndefined().util.isNumber().util.isObject().util.isPrimitive().util.isRegExp().util.isString().util.isSymbol().util.isUndefined().util.log().util._extend().zlib.bytesRead.- Internal process bindings for
async_wrap,crypto,http_parser,signal_wrap,url, andv8.
Removed command-line options
The following command-line options have been removed as they referred to features that are no longer experimental:
--no-experimental-global-customevent.--no-experimental-fetch.--no-experimental-global-webcrypto.
New runtime deprecations
Runtime deprecations result in warnings being printed to the console when first used.
SlowBufferclass.crypto.fips.fs.existsSyncwith invalid argument types.fs.F_OK,fs.R_OK,fs.W_OK,fs.X_OK.- Instantiating
node:replclasses withoutnew. - Instantiating
node:zlibclasses withoutnew. - Passing
argstonode:child_processexecFile/spawnwithshelloptiontrue. - Short GCM authentication tags without explicit
authTagLength. url.parse().
OpenSSL 3.5
Pre-built binaries of Node.js 24 LTS, or builds using the default build configuration options, include OpenSSL 3.5. While Node.js 22 LTS got OpenSSL 3.5 in Node.js 22.20.0, the default security level was lowered there to match the default security level in OpenSSL 3.0 of 1 to minimize disruption when updating within the Node.js 22 release line. Node.js 24 LTS uses the default security level from OpenSSL 3.5 of 2, which means that:
- RSA, DSA and DH keys shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited.
- Any cipher suite using RC4 is also prohibited.
Other changes of behavior
- Stricter
fetch()compliance, including removal of support for third partyBlob,FormData, andAbortController#56070. - Stricter validation of
AbortSignal#54965. CloseEvent,Float16ArrayandURLPatternhave now been added to the Global object.- Attempting to pipe to a closed or destroyed stream will now result in a
ERR_STREAM_UNABLE_TO_PIPEerror #53241. - The ESM CommonJS wrapper now exports 'module.exports' #53848.
buffer.Fileis now cloneable #47613.- New requests on existing HTTP/2 connections will not be able to do so once server close is initiated #57586.
- Streams now catch and forward errors from
dest.write()#55270. readlineno longer ignores unicode line separators #57591.- Calling
readline.pause(),readline.resume()orreadline.write()on a closedreadlineinterface now results in aERR_USE_AFTER_CLOSEerror #57680 - The
ERR_TLS_PSK_SET_IDENTIY_HINT_FAILEDerror has been corrected toERR_TLS_PSK_SET_IDENTITY_HINT_FAILED#52627. EventEmitterAsyncResourcefields are now private #54889.- Async context frame added to
AsyncResource#56082. AsyncLocalStoragenow defaults toAsyncContextFrame#55552.
Argument/option validation
The following API's have changed how arguments/options are validated:
- Buffer API's now throw when writing beyond the end of the buffer #54588.
- when writing a string to a buffer, or calling
buffer.toString()on a large buffer,buflenis now capped within integer range #51821. fs.symlink()no longer allows non-string values for thetypeoption #49741.timers.clearImmediatefor theimmediateargument #57069.- Timers now emit a warning if delay is negative or
NaN#46678. server.listen()host name validation #54470.- Long path names for pipes no longer truncate the pathname and instead throw an error #52347.
- string_decoder encoding validation #54957.
ERR_CRYPTO_SCRYPT_INVALID_PARAMETERhas been removed #53305.
Path handling
- Path handling on Windows with trailing slashes in
fsAPI's is now consistent with other platforms #54160. - Bugs and inconsistencies in
pathhandling #54224.
Test runner
WeakMapandWeakSetcomparison handling inassertandutilAPI's has been changed #53495.- Detect only tests when
--testis not used #54881. - The test runner now defaults to the
specreporter. TAP output is still available via the--test-reporter=tapCLI flag. #54548. - The
lcovreporter is now exposed as a newable function to allowoptionsto be set on it #52403.
C/C++ addons
Addons linking against V8 APIs may need to be updated for V8 13.6. This includes C++20 support needing to be enabled (previously C++17). Where possible, the project recommends using NODE-API to avoid needing to recompile for new versions of V8.
Building Node.js from source
If you are building Node.js from source, you may need to update your compiler toolchain.
- For AIX and Linux platforms, the minimum supported version of gcc is 12.2.
- For macOS the minimum supported version of Xcode is 16.1.
Node.js' configure script will warn if you attempt to build Node.js with a compiler toolchain that does not meet the minimum supported version but will not actively prevent you from trying.