JavaScriptDeveloper ToolsProgramming Languages

Node.js 24 LTS: OpenSSL 3.5 Breaks Keys, ESM Ships

Node.js 24 Krypton LTS release - OpenSSL 3.5 security level 2 and require ESM stable

Node.js 24 “Krypton” is now in Long-Term Support. If you’re running Node 20, your runtime hit end-of-life in April 2026 — six months ago. If you’re on Node 22, you’re in maintenance-only mode until April 2027, meaning security patches only, no new features. Node 24 is the active target, and it ships with two changes that will break things silently if you don’t check: OpenSSL 3.5 raises the default security level and rejects short cryptographic keys, and child process spawning now throws where it used to silently accept strings. The good news counterbalancing this: require() of ES modules is finally stable, and most teams can start deleting Babel configs.

OpenSSL 3.5 Will Quietly Break Your Legacy Integrations

This is the change most likely to cause production incidents during upgrades. Node.js 24 ships with OpenSSL 3.5, and critically, it sets the default security level to 2 — up from 1 in Node 22. Security level 2 is strict: RSA, DSA, and Diffie-Hellman keys under 2,048 bits are outright rejected, elliptic-curve keys under 224 bits are rejected, and all RC4 cipher suites are blocked.

Public-facing APIs using modern certificates won’t notice. What gets hit: corporate PKI systems, internal microservice mTLS, legacy vendor integrations, IoT device communication, anything using certificates generated more than a few years ago on a minimal-key-size standard. Before upgrading, run a quick check on every TLS endpoint your app talks to:

openssl s_client -connect yourhost:443 2>&1 | grep "Server public key"

If you see a key under 2,048 bits, it will fail after the upgrade. Regenerate the cert, remove RC4 from your cipher configuration, and test against a Node 24 build before you push. There’s no workaround — this is intentional hardening. The alternative is getting CVE’d for running ancient keys.

require(ESM) Is Stable — and That’s a Big Deal

For most teams this will be the headline feature. The ability to require() synchronous ES modules directly from CommonJS code is now stable in Node 24 — no experimental flag, no warnings. It was experimental since Node 22.12. Now it’s just how Node works.

Over 95% of ESM-only npm packages can be loaded with require() after this change. The one rule: the module cannot use top-level await. If it does, the call throws immediately. But for the vast majority of utility packages, this means you can stop running Babel transpilation just to consume them from CommonJS entry points.

// This just works in Node 24 — no flags, no transpilation
const utils = require('./utils.mjs')
const { parse } = require('esm-only-lib')

Teams maintaining dual CJS/ESM builds can start simplifying. Projects that added ts-node or Babel solely to bridge the module gap can audit whether they still need it. This is years of developer pain quietly resolved. For a deeper look at what this enables, see LogRocket’s full Node.js 24 breakdown.

Where Everyone Stands Right Now

The release schedule changed in 2026 to one major Node.js version per year, with every release becoming LTS. Here’s the current picture:

VersionStatusEOL
Node 20End of LifeApril 2026 — already dead
Node 22Maintenance LTSApril 2027 (security only)
Node 24Active LTSApril 2028
Node 26Current → LTS Oct 28April 2029

If you’re running Node 20, migration isn’t optional — it’s six months overdue. Node 24 is the production target. Node 26 enters Active LTS on October 28, which makes it a reasonable choice for new projects but too early for organizations that wait a cycle before adopting. The official Node.js release schedule lays out every support window.

AsyncLocalStorage Gets Faster — Automatically

AsyncLocalStorage now uses AsyncContextFrame as its default backing implementation, replacing the older async_hooks approach. No code changes required. The benefit is most visible in applications that pass request-scoped context through many async boundaries — SSR frameworks, APM agents, distributed tracing middleware. If you’re running Next.js or a custom tracing layer, this is a transparent performance gain. The --no-async-context-frame flag exists if you hit unexpected behavior and need to revert temporarily.

Two Quiet Breaking Changes to Search For

Beyond OpenSSL, two smaller breaking changes will surface latent bugs in your codebase:

Child process arguments must be arrays. child_process.spawn() and execFile() now throw a TypeError if you pass command arguments as a string instead of an array. This was always the safer API — it prevents shell injection. If your code was passing strings, it was technically wrong; Node 24 just stops letting it slide.

Buffer.write() now throws on out-of-range offsets. Previously, an out-of-range or fractional offset/length was silently clamped. Now it throws. Search your codebase for any Buffer.prototype.write() calls that pass dynamic offset values without bounds checking.

The Upgrade Is Worth It

Node.js 24 also bundles npm 11 (65% faster installs with parallel downloads and Lockfile v3), ships V8 13.6 with up to 30% faster execution on complex operations, adds Float16Array and URLPattern as globals, and promotes the permission model out of experimental. The runtime is substantially better than Node 22. The breaking changes are real but manageable — most teams will hit the OpenSSL issue or nothing at all. Check your TLS endpoints, audit your spawn calls, and test native addons against the new V8 ABI. Use the official Node.js v22-to-v24 migration guide as your checklist. Node 26 takes the Active LTS crown on October 28, but Node 24 is where production runs through 2028.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

    Your email address will not be published. Required fields are marked *

    More in:JavaScript