Node.js 24 LTS: Todas as Novas Features do V8 13.6, npm 11 e Melhorias de Performance
Ola HaWkers, o Node.js 24 chegou oficialmente em maio de 2025 e esta programado para entrar em LTS (Long-Term Support) em outubro. Essa versao traz uma quantidade impressionante de novas features JavaScript, melhorias de performance e APIs modernizadas.
Se voce trabalha com JavaScript no backend, este guia vai te mostrar tudo que precisa saber sobre a nova versao.
Overview do Node.js 24
O Node.js 24 representa um salto significativo em capacidades.
Principais atualizacoes:
| Componente | Versao Anterior | Node.js 24 |
|---|---|---|
| V8 Engine | 12.x | 13.6 |
| npm | 10.x | 11 |
| Undici | 6.x | 7 |
| libuv | 1.48 | 1.50 |
Timeline de suporte:
- Lancamento: Maio 2025
- LTS Ativo: Outubro 2025 - Abril 2027
- Manutencao: Abril 2027 - Abril 2028
Novas Features JavaScript
O V8 13.6 desbloqueia varias features ECMAScript modernas.
RegExp.escape
Finalmente temos uma forma nativa de escapar strings para uso em expressoes regulares.
// Antes - funcao manual (sujeita a bugs)
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// Agora - metodo nativo
const userInput = "Hello [World]! Price: $100";
const escaped = RegExp.escape(userInput);
// Resultado: "Hello \\[World\\]! Price: \\$100"
// Uso pratico em busca
function highlightText(text, searchTerm) {
const safeSearchTerm = RegExp.escape(searchTerm);
const regex = new RegExp(`(${safeSearchTerm})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
}
const result = highlightText(
"Preco: $50.00 (promocao)",
"$50.00"
);
// "<mark>$50.00</mark>" corretamente destacadoFloat16Array
Novo typed array para floats de 16 bits, ideal para ML e graficos.
// Float16Array - metade do tamanho de Float32Array
const float16Data = new Float16Array(4);
float16Data[0] = 1.5;
float16Data[1] = -2.25;
float16Data[2] = 3.14159; // Truncado para precisao de 16 bits
float16Data[3] = 0.0001;
console.log(float16Data.byteLength); // 8 bytes (vs 16 para Float32Array)
// Conversao entre tipos
const float32 = new Float32Array([1.5, 2.5, 3.5, 4.5]);
const float16 = new Float16Array(float32); // Conversao automatica
// Util para WebGL e Machine Learning
class NeuralNetworkLayer {
constructor(inputSize, outputSize) {
// Pesos em Float16 economizam memoria
this.weights = new Float16Array(inputSize * outputSize);
this.biases = new Float16Array(outputSize);
}
forward(input) {
// Computacao com precisao reduzida mas suficiente
const output = new Float16Array(this.biases.length);
// ... implementacao
return output;
}
}Error.isError
Verificacao nativa se um valor e realmente um objeto Error.
// Antes - verificacao manual (falha com objetos de outros realms)
function isErrorOld(value) {
return value instanceof Error;
}
// Agora - metodo nativo (funciona entre realms)
console.log(Error.isError(new Error('test'))); // true
console.log(Error.isError(new TypeError('test'))); // true
console.log(Error.isError(new RangeError('test'))); // true
console.log(Error.isError({ message: 'fake error' })); // false
console.log(Error.isError(null)); // false
// Uso pratico em error handling
function handleResponse(result) {
if (Error.isError(result)) {
logger.error('Operation failed:', result.message);
return { success: false, error: result.message };
}
return { success: true, data: result };
}
// Funciona com erros de iframes/workers
const iframe = document.createElement('iframe');
document.body.appendChild(iframe);
const IframeError = iframe.contentWindow.Error;
const iframeError = new IframeError('from iframe');
console.log(iframeError instanceof Error); // false (diferentes realms)
console.log(Error.isError(iframeError)); // true (funciona!)
Atomics.pause
Nova primitiva para sincronizacao de baixo nivel em Workers.
// Atomics.pause - util para spin-waiting eficiente
const sharedBuffer = new SharedArrayBuffer(4);
const sharedArray = new Int32Array(sharedBuffer);
// Worker esperando por valor
function waitForValue(expected) {
while (Atomics.load(sharedArray, 0) !== expected) {
// Pause permite que a CPU otimize o spin-wait
Atomics.pause();
}
return sharedArray[0];
}
// Main thread sinalizando
function signalWorker(value) {
Atomics.store(sharedArray, 0, value);
Atomics.notify(sharedArray, 0);
}
// Implementacao de spinlock
class SpinLock {
constructor(buffer, index) {
this.array = new Int32Array(buffer);
this.index = index;
}
acquire() {
while (Atomics.compareExchange(this.array, this.index, 0, 1) !== 0) {
Atomics.pause(); // CPU hint para aguardar
}
}
release() {
Atomics.store(this.array, this.index, 0);
}
}WebAssembly Memory64
Suporte a memoria de 64 bits para WebAssembly.
// WebAssembly com memoria de 64 bits
const memory64 = new WebAssembly.Memory({
initial: 1,
maximum: 65536, // Ate 4TB de memoria
index: 'i64', // Indexacao 64-bit
});
// Permite enderecar mais de 4GB de memoria
// Util para aplicacoes de big data e ML
// Exemplo de uso com modulo WASM
const wasmCode = await fetch('/module.wasm');
const wasmBuffer = await wasmCode.arrayBuffer();
const wasmModule = await WebAssembly.instantiate(wasmBuffer, {
env: {
memory: memory64,
},
});
// Processar datasets maiores que 4GB diretamente em WASM
const exports = wasmModule.instance.exports;
const result = exports.processLargeDataset(dataPointer, dataSize);
AsyncLocalStorage Melhorado
O AsyncLocalStorage agora usa AsyncContextFrame por padrao.
import { AsyncLocalStorage } from 'node:async_hooks';
const requestContext = new AsyncLocalStorage();
// Middleware Express/Fastify
function contextMiddleware(req, res, next) {
const context = {
requestId: crypto.randomUUID(),
userId: req.user?.id,
startTime: Date.now(),
};
requestContext.run(context, () => {
next();
});
}
// Logger que automaticamente inclui contexto
class ContextLogger {
log(message, data = {}) {
const ctx = requestContext.getStore();
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
requestId: ctx?.requestId,
userId: ctx?.userId,
message,
...data,
}));
}
// Novo: Performance melhorada com AsyncContextFrame
async logAsync(message) {
// Contexto preservado mesmo em operacoes async complexas
await someAsyncOperation();
this.log(message);
}
}
// Uso em qualquer lugar do codigo
const logger = new ContextLogger();
async function processOrder(orderId) {
logger.log('Processing order', { orderId });
// Mesmo em callbacks aninhados, contexto e preservado
await db.transaction(async (trx) => {
logger.log('Starting transaction');
await trx.insert('orders', { id: orderId });
logger.log('Order inserted');
});
logger.log('Order processed');
}Melhorias de performance:
| Operacao | Node.js 22 | Node.js 24 |
|---|---|---|
| getStore() | ~150ns | ~50ns |
| run() overhead | ~500ns | ~200ns |
| Nested contexts | Linear | Constante |
URLPattern Global
A API URLPattern agora esta disponivel globalmente.
// Antes - necessario import
// import { URLPattern } from 'urlpattern-polyfill';
// Agora - disponivel globalmente
const pattern = new URLPattern({
pathname: '/users/:userId/posts/:postId',
});
// Matching de URLs
const url1 = 'https://api.example.com/users/123/posts/456';
const match = pattern.exec(url1);
console.log(match.pathname.groups);
// { userId: '123', postId: '456' }
// Patterns mais complexos
const apiPattern = new URLPattern({
protocol: 'https',
hostname: '*.example.com',
pathname: '/api/v:version/:resource{/:id}?',
});
const testUrls = [
'https://api.example.com/api/v2/users',
'https://api.example.com/api/v2/users/123',
'https://cdn.example.com/api/v1/files/abc',
];
testUrls.forEach(url => {
const result = apiPattern.exec(url);
if (result) {
console.log('Match:', {
subdomain: result.hostname.groups[0],
version: result.pathname.groups.version,
resource: result.pathname.groups.resource,
id: result.pathname.groups.id,
});
}
});
// Router simples usando URLPattern
class PatternRouter {
constructor() {
this.routes = [];
}
add(method, patternString, handler) {
this.routes.push({
method,
pattern: new URLPattern({ pathname: patternString }),
handler,
});
}
match(method, url) {
for (const route of this.routes) {
if (route.method !== method) continue;
const match = route.pattern.exec(url);
if (match) {
return { handler: route.handler, params: match.pathname.groups };
}
}
return null;
}
}
const router = new PatternRouter();
router.add('GET', '/users/:id', getUserHandler);
router.add('POST', '/users', createUserHandler);
router.add('GET', '/posts/:postId/comments/:commentId?', getCommentsHandler);
npm 11
O npm 11 traz melhorias significativas.
Performance de Instalacao
# Instalacao mais rapida com cache otimizado
npm install
# Benchmark comparativo (projeto medio ~500 deps)
# npm 10: 45 segundos
# npm 11: 28 segundos (-38%)
# Novo algoritmo de resolucao de dependencias
# Menos duplicacao, arvore mais flatNovos Comandos e Flags
# Query melhorada de dependencias
npm query ":root > :has([name^=@types/])"
# Lista todas as dependencias de tipos diretas
# Audit com mais detalhes
npm audit --format=json --detail
# Pack com preview
npm pack --dry-run --json
# Mostra exatamente o que seria incluido
# Instalacao seletiva
npm install --omit=dev --omit=optional --omit=peer
# Verificacao de integridade melhorada
npm doctor --fix
# Corrige problemas automaticamente quando possivelWorkspaces Aprimorados
# Execucao paralela em workspaces
npm run build --workspaces --parallel
# Filtragem por workspace
npm run test --workspace=packages/core --workspace=packages/utils
# Publicacao coordenada
npm publish --workspaces --tag latest
# Dependencias entre workspaces
npm install @myorg/utils --workspace=packages/core
Test Runner Nativo Melhorado
O test runner do Node.js recebeu melhorias significativas.
import { describe, it, before, after, mock } from 'node:test';
import assert from 'node:assert';
describe('UserService', () => {
let db;
let service;
before(async () => {
db = await createTestDatabase();
service = new UserService(db);
});
after(async () => {
await db.close();
});
// Novo: Subtests nao precisam mais de await explicito
it('should create user', async (t) => {
const user = await service.create({
name: 'Test User',
email: 'test@example.com',
});
// Subtests gerenciados automaticamente
t.test('should have valid id', () => {
assert.ok(user.id);
assert.match(user.id, /^[a-f0-9-]{36}$/);
});
t.test('should have timestamps', () => {
assert.ok(user.createdAt instanceof Date);
assert.ok(user.updatedAt instanceof Date);
});
});
// Novo: Mocking melhorado
it('should send welcome email', async (t) => {
const sendEmail = t.mock.fn(async () => ({ sent: true }));
// Mock de modulo
t.mock.module('../email-service.js', {
namedExports: { sendEmail },
});
await service.create({ name: 'Test', email: 'test@test.com' });
assert.strictEqual(sendEmail.mock.calls.length, 1);
assert.strictEqual(
sendEmail.mock.calls[0].arguments[0],
'test@test.com'
);
});
// Novo: Snapshot testing
it('should format user correctly', async (t) => {
const user = await service.getById('user-123');
t.assert.snapshot(user);
});
});Executando testes:
# Executar todos os testes
node --test
# Com coverage
node --test --experimental-test-coverage
# Watch mode
node --test --watch
# Filtrar por nome
node --test --test-name-pattern="UserService"
# Reporter personalizado
node --test --test-reporter=spec
Undici 7
O cliente HTTP padrao foi atualizado para Undici 7.
import { request, fetch, Agent, Pool } from 'undici';
// Fetch com mais controle
const response = await fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ query: 'test' }),
// Novo: Controle de timeout granular
signal: AbortSignal.timeout(5000),
});
// Pool de conexoes otimizado
const pool = new Pool('https://api.example.com', {
connections: 10,
pipelining: 6,
keepAliveTimeout: 30000,
keepAliveMaxTimeout: 60000,
});
// Requests usando pool
const { statusCode, body } = await pool.request({
path: '/users',
method: 'GET',
});
const data = await body.json();
// Agent customizado para retry
const retryAgent = new Agent({
connect: {
timeout: 10000,
},
// Novo: Retry automatico
retry: {
maxRetries: 3,
minTimeout: 100,
maxTimeout: 1000,
},
});
// Streaming melhorado
const streamResponse = await fetch('https://api.example.com/stream', {
dispatcher: retryAgent,
});
for await (const chunk of streamResponse.body) {
process.stdout.write(chunk);
}
Deprecacoes e Remocoes
Algumas APIs foram depreciadas ou removidas.
url.parse() Depreciado
// Depreciado
import { parse } from 'node:url';
const parsed = parse('https://example.com/path?query=1');
// Recomendado: WHATWG URL API
const url = new URL('https://example.com/path?query=1');
console.log(url.hostname); // 'example.com'
console.log(url.pathname); // '/path'
console.log(url.searchParams.get('query')); // '1'
// Migracao de codigo legado
// Antes
const oldUrl = parse('https://user:pass@example.com:8080/path?q=1#hash');
console.log(oldUrl.auth); // 'user:pass'
// Depois
const newUrl = new URL('https://user:pass@example.com:8080/path?q=1#hash');
console.log(newUrl.username); // 'user'
console.log(newUrl.password); // 'pass'tls.createSecurePair Removido
// Removido: tls.createSecurePair()
// Use tls.TLSSocket diretamente
import tls from 'node:tls';
import net from 'node:net';
const socket = net.connect(443, 'example.com');
const tlsSocket = new tls.TLSSocket(socket, {
// opcoes
});
Migrando do Node.js 22
Guia pratico para atualizacao.
Checklist de Migracao
# 1. Verificar versao atual das dependencias
npm outdated
# 2. Atualizar dependencias que podem ter problemas
npm update
# 3. Verificar uso de APIs depreciadas
npx depcheck
# 4. Testar com Node.js 24
nvm install 24
nvm use 24
npm test
# 5. Verificar compatibilidade de native modules
npm rebuild
# 6. Atualizar engines no package.json{
"engines": {
"node": ">=24.0.0"
}
}Breaking Changes Importantes
Mudancas que podem afetar seu codigo:
url.parse()agora emite warning de depreciacaotls.createSecurePairfoi removido- Algumas flags experimentais foram removidas
--experimental-specifier-resolutionremovido (use import maps)
Conclusao
O Node.js 24 representa uma evolucao significativa da plataforma. Com o V8 13.6, ganhamos features JavaScript modernas como RegExp.escape e Float16Array. O npm 11 traz instalacoes mais rapidas e workspaces aprimorados. O test runner nativo esta cada vez mais completo.
Para quem esta em producao com Node.js 20 ou 22, a migracao para 24 LTS (quando disponivel em outubro) sera tranquila para a maioria dos projetos. As depreciacoes sao poucas e bem documentadas.
Se voce quer explorar mais sobre o ecossistema JavaScript moderno, confira nosso artigo sobre ECMAScript 2025 e Novas Features JavaScript.
Bora pra cima! 🦅
📚 Quer Dominar Node.js do Zero ao Avancado?
Este artigo mostrou as novidades do Node.js 24, mas para aproveitar todo o potencial da plataforma, voce precisa de fundamentos solidos.
Material de Estudo Completo
Se voce quer construir uma base solida em JavaScript para dominar Node.js:
Opcoes de investimento:
- 1x de R$9,90 no cartao
- ou R$9,90 a vista
💡 JavaScript solido = Node.js dominado

