Node.js 24 officially launched on May 6, 2025, bringing a massive set of new features, performance improvements, and modern JavaScript capabilities. Set to enter LTS (Long-Term Support) in October 2025 with support until April 2028, this release is packed with upgrades that will transform how you build server-side applications.
Whether you're building microservices, APIs, or full-stack applications, Node.js 24 has something for everyone. Let's dive into what's new and how you can upgrade smoothly!
Node.js 24 ships with V8 13.6, bringing significant performance improvements and modern JavaScript features. This upgrade alone makes Node.js 24 worth the upgrade, with faster execution times and reduced memory consumption across the board.
One of the standout features is the new Float16Array typed array, which provides 16-bit floating-point numbers. This is a game-changer for:
// Using Float16Array for memory-efficient ML model weights
const modelWeights = new Float16Array(1000000);
// Save 50% memory compared to Float32Array
console.log(modelWeights.byteLength); // 2MB instead of 4MB
// Perfect for graphics processing
const pixelData = new Float16Array([0.5, 0.75, 1.0, 0.25]);
The memory savings are substantial - Float16Array uses half the memory of Float32Array while maintaining reasonable precision for most use cases.
using
Node.js 24 introduces explicit resource management through the new using
statement, providing automatic cleanup of resources like file handles, database connections, and network sockets.
import { open } from 'fs/promises';
async function processFile() {
// Automatic cleanup when scope exits
using file = await open('data.txt');
const content = await file.readFile('utf8');
console.log(content);
// File is automatically closed here, even if an error occurs
}
// Database connection example
async function queryDatabase() {
using connection = await connectToDatabase();
const results = await connection.query('SELECT * FROM users');
// Connection is automatically closed, no .finally() needed!
return results;
}
This eliminates the need for try-finally blocks and ensures resources are properly cleaned up, even when exceptions occur. No more leaked file descriptors or hanging database connections!
Node.js 24 adds support for 64-bit memory addressing (Memory64) in WebAssembly, breaking through the previous 4GB memory limit. This is crucial for:
// Now you can work with WebAssembly modules that require >4GB memory
const wasmModule = await WebAssembly.instantiate(wasmBytes, {
env: {
memory: new WebAssembly.Memory({
initial: 1024,
maximum: 65536, // Much larger than before
index: 'i64' // 64-bit addressing
})
}
});
The new RegExp.escape() method safely escapes special characters in strings for use in regular expressions. No more manually escaping regex characters!
// Before Node.js 24 - manual escaping
const userInput = 'price: $50 (50% off)';
const escaped = userInput.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// Node.js 24 - built-in escaping
const safePattern = RegExp.escape(userInput);
const regex = new RegExp(safePattern);
// Perfect for dynamic search patterns
function searchInText(text, userQuery) {
const safeQuery = RegExp.escape(userQuery);
const pattern = new RegExp(safeQuery, 'gi');
return text.match(pattern);
}
The URLPattern constructor is now available globally, eliminating the need for explicit imports. This makes URL routing and pattern matching much more convenient:
// No imports needed!
const pattern = new URLPattern({ pathname: '/users/:id' });
const match = pattern.exec('https://api.example.com/users/123');
console.log(match.pathname.groups.id); // "123"
// Perfect for custom routing logic
const routes = [
new URLPattern({ pathname: '/api/users/:userId/posts/:postId' }),
new URLPattern({ pathname: '/api/products/:category/:id' }),
];
function findRoute(url) {
for (const pattern of routes) {
const match = pattern.exec(url);
if (match) return match;
}
}
The built-in test runner now intelligently manages test lifecycles without requiring explicit await statements for subtests. This makes writing tests more intuitive:
import { test } from 'node:test';
import assert from 'node:assert';
test('user authentication', async (t) => {
// No need to await subtests anymore!
t.test('should login with valid credentials', () => {
const result = login('user@example.com', 'password');
assert.ok(result.success);
});
t.test('should reject invalid credentials', () => {
const result = login('user@example.com', 'wrong');
assert.strictEqual(result.success, false);
});
// Test runner handles lifecycle automatically
});
Node.js 24 ships with npm 11, bringing:
# npm 11 is blazing fast
npm install express
# Noticeably faster than npm 10
Node.js 24 includes Undici 7, the high-performance HTTP client that powers fetch()
:
// Using the built-in fetch powered by Undici 7
const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John' })
});
const data = await response.json();
The legacy url.parse()
API is now deprecated. Use the WHATWG URL API instead:
// β Deprecated - url.parse()
const url = require('url');
const parsed = url.parse('https://example.com/path?query=value');
// β
Use WHATWG URL API
const urlObject = new URL('https://example.com/path?query=value');
console.log(urlObject.pathname); // "/path"
console.log(urlObject.searchParams.get('query')); // "value"
The deprecated tls.createSecurePair()
method has been removed. Use tls.TLSSocket
instead:
// β Removed - tls.createSecurePair()
const pair = tls.createSecurePair(credentials);
// β
Use TLSSocket
const socket = new tls.TLSSocket(tcpSocket, {
isServer: false,
server: null,
requestCert: true,
rejectUnauthorized: true
});
node --version
# v20.x.x or earlier
Using nvm (recommended):
# Install nvm if you haven't already
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# Install Node.js 24
nvm install 24
# Set it as default
nvm alias default 24
# Verify installation
node --version
# v24.0.0
Using official installer:
# macOS with Homebrew
brew update
brew upgrade node
# Ubuntu/Debian
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
# Windows - Download from nodejs.org
Update the engines field to specify Node.js 24:
{
"engines": {
"node": ">=24.0.0",
"npm": ">=11.0.0"
}
}
# Remove old node_modules and lock files
rm -rf node_modules package-lock.json
# Clean npm cache
npm cache clean --force
# Reinstall dependencies
npm install
# Check for outdated packages
npm outdated
# Update packages
npm update
# Run your test suite
npm test
# Check for deprecation warnings
node --trace-warnings app.js
Search your codebase for deprecated APIs:
# Find url.parse() usage
grep -r "url.parse" src/
# Find tls.createSecurePair() usage
grep -r "createSecurePair" src/
# Update @types/node
npm install --save-dev @types/node@24
# Update TypeScript if needed
npm install --save-dev typescript@latest
Update your tsconfig.json
:
{
"compilerOptions": {
"target": "ES2023",
"lib": ["ES2023"],
"module": "NodeNext",
"moduleResolution": "NodeNext"
}
}
Update your GitHub Actions, GitLab CI, or other CI/CD configurations:
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [24.x]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
# Use Node.js 24 Alpine for smaller images
FROM node:24-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
CMD ["node", "app.js"]
Deploy to staging first and monitor for:
// Add monitoring for Node.js version
console.log('Node.js version:', process.version);
console.log('V8 version:', process.versions.v8);
// Monitor memory usage
setInterval(() => {
const usage = process.memoryUsage();
console.log('Memory usage:', {
heapUsed: `${Math.round(usage.heapUsed / 1024 / 1024)}MB`,
heapTotal: `${Math.round(usage.heapTotal / 1024 / 1024)}MB`,
});
}, 60000);
package.json
engines fieldnode_modules
and reinstall dependenciesurl.parse()
with WHATWG URL APItls.createSecurePair()
with tls.TLSSocket
@types/node@24
node:24
// Before: Using Float32Array
const weights = new Float32Array(10000000); // 40MB
// After: Using Float16Array
const weights = new Float16Array(10000000); // 20MB (50% savings!)
// Cleaner, safer file operations
async function processLargeFile(filename) {
using file = await open(filename);
using writeStream = createWriteStream('output.txt');
for await (const line of file.readLines()) {
writeStream.write(processLine(line));
}
// Everything is automatically cleaned up!
}
// Safe and fast dynamic patterns
function createSearchPattern(userInput) {
const escaped = RegExp.escape(userInput);
return new RegExp(`\\b${escaped}\\b`, 'i');
}
Node.js 24 is a significant upgrade that brings modern JavaScript features, better performance, and improved developer experience. With V8 13.6, Float16Array, explicit resource management, and WebAssembly Memory64, you'll be able to build faster, more efficient applications.
The upgrade process is straightforward if you follow the steps above, and the benefits far outweigh the minimal migration effort. With LTS support until April 2028, Node.js 24 is a solid foundation for your next project.
Ready to upgrade? Start with a staging environment, run your tests, and gradually roll out to production. Your applications will thank you for it!
Happy Grizzly Coding π»!
Node.js has memory limitations that you can hit quite easily in production. By default, Node.js uses a maximum heap size of 700MB and 1400MB on 32-bit and 64-bit platforms.
Ever wanted to be a Promises whizz. There are a few tricks you can learn to become that through the use of promise static methods for handling an array of promises in JavaScript
In this post, we will see how to perform remote debugging on a server running heedlessly leveraging the power of an SSH tunnel.