Node.js 22 became the current LTS in October 2025, and it's a significant release. Let's go through what actually changed and what it means for your projects.
Native TypeScript Support (Type Stripping)
This is the headline feature. You can now run .ts files directly:
node --experimental-strip-types server.ts
Node strips the type annotations before executing — it doesn't type-check. Think of it as a lightweight alternative to ts-node for running scripts without a build step.
[!IMPORTANT] This is type stripping only — not full TypeScript compilation. Features like
enum,namespace, and decorators (pre-standard) are not supported. For production TypeScript compilation, you still wanttscor a bundler.
For most utility scripts and quick prototypes, it's exactly what you need.
require(esm) Is Now Stable
The long-standing headache of importing ES modules in CommonJS code is resolved:
// In a CommonJS file (.cjs or "type": "commonjs")
const { something } = require('./esm-module.mjs'); // Now works!
const chalk = require('chalk'); // ESM-only package — now works!
This eliminates the ERR_REQUIRE_ESM error that forced either converting your entire project to ESM or maintaining awkward dynamic import workarounds.
Built-in WebSocket Client
Node.js now ships a native WebSocket client, matching the browser's WebSocket API:
const ws = new WebSocket('wss://api.example.com/realtime');
ws.onopen = () => {
ws.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
};
ws.onmessage = ({ data }) => {
console.log('Received:', JSON.parse(data));
};
No more ws package for simple client-side WebSocket connections.
Improved Test Runner
Node's built-in node:test module gets meaningful upgrades:
import { test, describe, beforeEach } from 'node:test';
import assert from 'node:assert/strict';
describe('User service', () => {
let userService;
beforeEach(() => {
userService = new UserService({ db: mockDb });
});
test('returns user by ID', async () => {
const user = await userService.findById('user-1');
assert.equal(user.name, 'Alice');
});
test('throws when user not found', async () => {
await assert.rejects(
() => userService.findById('nonexistent'),
{ name: 'NotFoundError' }
);
});
});
Run with node --test — no additional tools needed for basic test suites.
AbortSignal.timeout() Improvements
Cleaner timeout handling without manual cleanup:
const controller = new AbortController();
// Automatically aborts after 5 seconds
const response = await fetch('https://api.example.com/data', {
signal: AbortSignal.timeout(5000),
});
Performance Improvements
| Operation | Node.js 20 | Node.js 22 | Improvement |
|---|---|---|---|
| URL parsing | 100% | 174% | +74% |
| Buffer operations | 100% | 143% | +43% |
fs.readFile | 100% | 128% | +28% |
| HTTP/1.1 throughput | 100% | 115% | +15% |
Upgrade Path
# With nvm
nvm install 22
nvm use 22
# With fnm (faster alternative to nvm)
fnm install 22
fnm use 22
# Verify
node --version # v22.x.x
Breaking changes to watch for:
--experimental-fetchflag removed (Fetch is now stable and always on)punycodemodule deprecated (usewhatwg-urlinstead)- Minimum OpenSSL version bumped to 3.0
Should You Upgrade?
If you're on Node.js 18 LTS: Yes, plan the upgrade. Node.js 18 goes EOL in April 2025.
If you're on Node.js 20 LTS: Eventually yes, but Node.js 20 is supported until April 2026.
For new projects starting today: Start on 22.
Tagged with
Written by
DebuggerMe TeamThe DebuggerMe team builds developer tools, writes technical content, and helps teams ship better software.
Related Articles
All articles →package.json vs package-lock.json – What's the Difference?
Understanding why both package.json and package-lock.json exist in your Node.js project, and when each file matters.
Why TypeScript Generics Are More Powerful Than You Think
A deep dive into TypeScript's generic type system — from basic usage to advanced patterns like conditional types, infer, and mapped types that will make your code safer and more expressive.
Docker for Developers — From Zero to Production-Ready in One Guide
Docker is non-negotiable in modern development. This guide takes you from installing Docker to running a full multi-service production stack with zero fluff and working code at every step.