Node.js
Deep dive em Node.js como runtime JavaScript para backend — event-driven, non-blocking I/O, ecossistema npm. Para fundamentos da linguagem (event loop, closures, async), ver JavaScript Fundamentals. Para TypeScript, ver TypeScript. Para testes, ver Testes em JavaScript.
O que é
Node.js é um runtime JavaScript criado por Ryan Dahl em 2009, baseado no V8 engine do Chrome com libuv para I/O assíncrono. Projetado para servidores I/O-bound de alta concorrência, é a base da maioria dos backends JavaScript modernos, ferramentas (build tools, CLIs) e package management.
Em 2026:
- Node 22 LTS é o current stable, Node 24 iteration current
- Suporte nativo a TypeScript via
--experimental-strip-types(22.18+), estável em 24+ - ESM é default para novos projetos
- Bun (agora da Anthropic) e Deno são concorrentes sérios
- Virtual Threads na JVM e Go tornaram Node menos dominante em I/O-bound puro, mas ecossistema npm continua imbatível
- test runner nativo (
node --test) ganhou features, competitivo com Vitest - watch mode nativo (
node --watch) substitui nodemon
Em entrevistas, o que diferencia um senior em Node.js:
- Event loop phases (libuv) — timers, pending, poll, check, close
- Streams — Readable, Writable, Transform, Duplex, backpressure
- Error handling — unhandledRejection, uncaughtException, domain (deprecated)
- Cluster vs Worker Threads vs child_process — quando cada um
- Frameworks — Express, Fastify, NestJS, Hono — trade-offs
- Performance — profiling, —inspect, clinic.js, autocannon
- Security — npm audit, supply chain, secrets, input validation
- Moderno — ESM, TypeScript nativo, built-in test runner, watch mode
- Integrações — Postgres, Redis, Kafka, gRPC, GraphQL
Como funciona
Arquitetura
Migrado para galho próprio
A anatomia interna do runtime — V8, libuv, thread pool — foi expandida em index. Veja em particular 02 - V8, libuv e thread pool (componentes), 01 - Single-thread e non-blocking I-O (modelo), e 07 - I-O assíncrono - kernel vs thread pool (onde o paralelismo verdadeiro mora).
Single-threaded com non-blocking I/O
Migrado para galho próprio
O modelo single-thread + non-blocking I/O foi expandido em 01 - Single-thread e non-blocking I-O dentro do galho index.
Event loop phases — detalhado
Migrado para galho próprio
As fases do event loop foram expandidas em index. Veja em particular 04 - As fases do event loop (ciclo libuv), 05 - Microtasks - nextTick, queueMicrotask, Promise.then (microtasks), e 06 - Macrotasks e timers - setTimeout, setInterval, setImmediate (timers).
Worker Threads, cluster, child_process — as 3 formas de paralelismo
Migrado para galho próprio
As 3 ferramentas de paralelismo foram expandidas em index (galho 2). Veja em particular 02 - As 3 ferramentas - Worker Threads, Cluster, child_process (visão geral comparativa), 03 - Worker Threads - fundamentos (Worker Threads), 07 - Cluster - escalando HTTP por CPU (Cluster), 08 - child_process com exec e spawn (rodar comandos externos) e 09 - child_process com fork - Node child com IPC (Node child isolado). Decision tree completa em 11 - Decision tree - qual ferramenta para qual problema.
Frameworks
Migrado para galho próprio
Os 4 frameworks principais foram expandidos em index (galho 4). Veja em particular 01 - Os 4 frameworks - Express, NestJS, Fastify, Hono (visão geral comparativa), 02 - Express idiomático (Express moderno), 03 - NestJS - fundamentos (DI + módulos), 05 - Fastify - schema-first, plugins, performance (Fastify) e 06 - Hono e edge runtimes (edge-first).
Error Handling
Migrado para galho próprio
Error handling estruturado (Problem Details RFC 7807) foi expandido em 08 - Error handling estruturado no galho index, com implementação em todos os 4 frameworks principais.
Streams — deep dive
Migrado para galho próprio
Os 4 tipos de stream foram expandidos em index (galho 3). Veja em particular 02 - Os 4 tipos - Readable, Writable, Duplex, Transform (visão geral comparativa), 03 - Readable streams (Readable detalhado), 04 - Writable streams (Writable detalhado) e 05 - Duplex e Transform (Duplex vs Transform).
Backpressure
Migrado para galho próprio
Backpressure como mecânica explícita foi expandido em 06 - Backpressure no galho index.
Web Streams vs Node streams
Migrado para galho próprio
Interop Node ↔ Web Streams foi expandido em 09 - Web Streams - interop com padrão universal no galho index.
Stream patterns
Migrado para galho próprio
Padrões práticos (line parser, CSV → JSONL, fetch streaming, multipart, tee) foram expandidos em 10 - Padrões práticos no galho index. Decision tree e armadilhas em 12 - Armadilhas, regras práticas, cheatsheet.
npm e Package Management
Migrado para galho próprio
Package managers, semver e ecossistema npm foram expandidos em index (galho 7). Veja em particular 01 - Package managers - npm, pnpm, yarn e bun (comparativo dos 4 gerenciadores: npm v10, pnpm v9, yarn v4 Berry, bun v1.1+) e 02 - Semver e gerenciamento de dependências (versionamento semântico, lockfiles e estratégias de atualização automatizada com Renovate/Dependabot).
Node moderno — features que você deveria usar
Migrado para galho próprio
As features modernas do Node foram expandidas em index (galho 7). Veja em particular 04 - TypeScript nativo - strip types e integração (
--experimental-strip-typesno Node 22.18+), 05 - Built-in test runner - node-test (node:testcom mock e watch), 06 - DX flags modernos - watch, env-file e import (--watch,--env-file), 07 - Single Executable Apps (SEA) e 08 - Promise-based core APIs (fs/promises,timers/promises,stream/promises).
Quando usar
- Node.js: APIs REST/GraphQL, real-time (WebSocket), microserviços I/O-bound, BFF (Backend for Frontend)
- Não usar: CPU-bound heavy (image processing, ML inference) — melhor com Python ou Go
- NestJS: quando precisa de estrutura enterprise, DI, e padrões familiares do Spring
- Express: APIs simples, prototipagem rápida
Armadilhas comuns
- Blocking the event loop: Sintomas, causas e diagnóstico em 10 - Bloqueio do event loop - sintomas e causas e 11 - Diagnóstico do event loop (galho index).
- Unhandled promise rejections: promises sem
.catch()ou try/catch em async. Configurarprocess.on('unhandledRejection'). - Callback hell: aninhar callbacks. Usar async/await.
- Memory leaks: event listeners não removidos, closures que retêm referências grandes, caches sem TTL.
requirevsimport: CJS (require) é síncrono, ESM (import) é assíncrono. Projetos novos devem usar ESM.
Na prática (da minha experiência)
Em projetos fullstack, uso Node.js com NestJS ou Express como BFF (Backend for Frontend) que agrega dados de microserviços Java. A vantagem é compartilhar types TypeScript entre frontend React e backend Node. Para APIs que fazem muitas chamadas a serviços externos (I/O-bound), Node.js performa melhor que Java com menos recursos, graças ao event loop non-blocking.
How to explain in English
“Node.js is my choice for I/O-bound backend services. Its event loop model means a single process can handle thousands of concurrent connections without the overhead of thread management. This is particularly effective for API gateways or BFF services that aggregate data from multiple microservices.
I typically use NestJS for larger applications because it provides structure similar to Spring Boot — dependency injection, modules, guards, and interceptors. For simpler services, Express with TypeScript is my go-to.
One critical thing about Node.js is knowing when NOT to use it. CPU-intensive operations block the event loop and degrade performance for all concurrent requests. For heavy computation, I’d use Worker Threads or offload to a different service. In a microservices architecture, I use Node.js for the API layer and Java for services that need heavy processing or complex business logic.
Error handling in Node.js requires attention — especially with async code. I always use a global error handler middleware and wrap async route handlers to catch unhandled promise rejections. In NestJS, exception filters handle this elegantly.”
Key vocabulary
- laço de eventos → event loop
- I/O não-bloqueante → non-blocking I/O
- thread de trabalho → worker thread
- fluxo de dados → stream
- middleware → middleware: função que intercepta requisições
- gerenciador de pacotes → package manager (npm, pnpm)
- módulo → module: unidade de código importável
ORMs
Sequelize — ORM para Node.js com suporte a PostgreSQL, MySQL, SQLite:
// Model
@Table
class Patient extends Model {
@Column declare name: string;
@Column declare email: string;
@HasMany(() => Appointment) declare appointments: Appointment[];
}
// Query
const patients = await Patient.findAll({
where: { active: true },
include: [Appointment], // eager loading (evita N+1)
limit: 20,
offset: 0,
});Cuidados com Sequelize:
- Associações mal configuradas causam queries inesperadas
- Paginação: usar
limit+offsetou cursor-based para datasets grandes - Migrations versionadas (similar ao Flyway do Java)
Alternativas: Prisma (type-safe, schema-first), TypeORM (decorators, similar ao JPA), Drizzle (lightweight).
Fontes:
Troubleshooting em produção
Problemas recorrentes em aplicações Node.js — equivalentes aos problemas de Java/Spring Boot, mas com soluções idiomáticas do ecossistema Node.
Connection pool exausto
Migrado para galho próprio
Configuração, diagnóstico e anti-padrões de connection pool foram expandidos em index: 11 - Connection pool tuning.
N+1 queries
Com Sequelize:
// RUIM — N+1
const doctors = await Doctor.findAll();
for (const d of doctors) {
const appointments = await d.getAppointments(); // 1 query por doctor
}
// BOM — eager loading
const doctors = await Doctor.findAll({
include: [{ model: Appointment }], // JOIN
});
// BOM — DataLoader pattern (GraphQL)
const appointmentLoader = new DataLoader(async (doctorIds) => {
const appointments = await Appointment.findAll({
where: { doctorId: doctorIds },
});
return doctorIds.map(id => appointments.filter(a => a.doctorId === id));
});Com Prisma:
// BOM — include (eager)
const doctors = await prisma.doctor.findMany({
include: { appointments: true },
});
// BOM — select (projection)
const doctors = await prisma.doctor.findMany({
select: { name: true, _count: { select: { appointments: true } } },
});Event loop blocking
Migrado para galho próprio
Sintomas, causas e ferramentas de diagnóstico foram expandidos em index: 10 - Bloqueio do event loop - sintomas e causas e 11 - Diagnóstico do event loop.
Memory leak
Migrado para galho próprio
Diagnóstico, causas comuns e técnicas de detecção foram expandidos em index: 08 - Detecção e diagnóstico de memory leaks.
Graceful shutdown
Migrado para galho próprio
Padrão completo para Express e NestJS, com tratamento de conexões e timeout de força, foi expandido em index: 09 - Graceful shutdown profundo.
Circuit breaker
Migrado para galho próprio
Implementação com opossum, estados (closed/open/half-open) e padrões de fallback foram expandidos em index: 10 - Circuit breaker e fallback com opossum.
→ Para comparação cross-stack: System Design (seção Problemas comuns em produção)
Recursos
- Node.js Docs — documentação oficial
- NestJS Docs — framework enterprise
- Full Stack Open — curso gratuito de fullstack com Node/React
- Clean Code JavaScript — boas práticas
- Mastering Node.js and Express
- Senda JS-TS — trilha de aprendizado
Veja também
- index — galho 1 da trilha Node Senior; deep dive do motor (single-thread, libuv, fases, microtasks, async/await, bloqueio, diagnóstico)
- index — galho 2 da trilha Node Senior; as 3 ferramentas de paralelismo (Worker Threads, Cluster, child_process), SharedArrayBuffer/Atomics, pool de workers, decision tree
- index — galho 3 da trilha Node Senior; abstração fundamental para processar dados em chunks (4 tipos, backpressure, pipeline, async iter, Web Streams, padrões práticos)
- index — galho 4 da trilha Node Senior; os 4 frameworks principais (Express, NestJS, Fastify, Hono), patterns transversais e arquitetura
- index — galho 5 da trilha Node Senior; logs, métricas, traces, profiling, SLOs, dashboards, alertas e checklists de produção
- index — galho 6 da trilha Node Senior; os 4 ORMs principais (Sequelize, Prisma, TypeORM, Drizzle), N+1, migrations, transações, decision tree
- index — galho 7 da trilha Node Senior; package managers (npm, pnpm, yarn, Bun), semver, ESM vs CJS, TypeScript nativo, test runner nativo, DX flags, SEA e Bun como runtime
- Segurança — galho 8 da trilha Node Senior; supply chain, segredos, validação, JWT, OAuth 2.0, RBAC, rate limiting, Helmet.js e OWASP Top 10
- index — galho 9 da trilha Node Senior; PostgreSQL, Redis, BullMQ, Kafka, gRPC, GraphQL, WebSockets, HTTP clients e padrões de resiliência
- JavaScript Fundamentals — linguagem, event loop, async
- TypeScript — tipagem em Node
- Testes em JavaScript — Vitest, MSW, built-in test runner
- React — frontend companion
- API Design — REST, JWT, contratos
- Full Stack Open - Guia de Revisão — partes 3, 4 sobre Node + Express
- System Design — troubleshooting cross-stack, building blocks
- Kafka — Node.js com Kafka
- BullMQ — job queue em Node.js
- Arquitetura de Software — Clean Architecture em Node