O que é o Node.js na prática
O Node.js é um programa que você instala na sua máquina para executar arquivos JavaScript. Essa é a descrição mais simples possível — e é exatamente isso. Quando você roda node script.js, o Node lê o arquivo, entrega ele para o V8 (a engine JavaScript do Google, a mesma do Chrome) e manda executar, com uma biblioteca gigante de APIs extras acopladas para fazer coisas que o V8 sozinho não dá conta.
O V8 sabe rodar JavaScript. Só que ele não sabe abrir um arquivo, escutar em um socket TCP, iniciar um processo ou ler uma variável de ambiente. Tudo isso quem entrega é o Node, escrito em C++, expondo essas funcionalidades para o seu JavaScript como módulos nativos.
node --version
node script.js
Então o Node não é uma linguagem. Também não é um framework. Ele é um runtime JavaScript: o V8 somado a uma biblioteca padrão, um sistema de módulos e um event loop. É isso aí — nada mais, nada menos.
Seu primeiro script em Node.js
Qualquer arquivo .js já é um programa Node válido. Sem boilerplate, sem função main:
console.log funciona igualzinho ao do navegador. Template literals, Date, arrays, promises — todos os recursos da linguagem que você já conhece vêm do V8 e se comportam da mesma forma. O que muda no Node é o que está disponível ao redor da linguagem.
Variáveis globais que só existem no Node
No navegador você tem window, document, localStorage, fetch. Já o Node traz um conjunto diferente de globais, pensados para um runtime do lado do servidor:
processé o processo Node em execução. Ele carrega as variáveis de ambiente (process.env), os argumentos da linha de comando (process.argv) e métodos para encerrar o processo (process.exit(1)).__filenamee__dirnamedevolvem o caminho absoluto do arquivo atual e da pasta em que ele está. (Em ES modules eles não existem — nesse caso você usaimport.meta.url.)globalé o objeto de nível mais alto, o equivalente aowindowdo navegador.
No Node não existe document nem window. Se você tentar usar, leva um ReferenceError na cara. Esse geralmente é o primeiro sinal de que a biblioteca foi escrita para o browser e não vai rodar no Node sem adaptação.
Argumentos da linha de comando e variáveis de ambiente
Boa parte do que se faz com Node — CLIs, scripts de build, servidores — depende de ler argumentos e variáveis de ambiente. Os dois vivem dentro de process:
process.argv é um array: os dois primeiros itens são o caminho do binário do Node e o caminho do script, então os argumentos de verdade começam no índice 2. Já process.env é um objeto comum com as variáveis de ambiente — ler NODE_ENV, PORT ou chaves de API a partir dele é prática padrão.
Módulos nativos do Node.js
O Node vem com uma biblioteca padrão que você acessa via require (CommonJS) ou import (ESM). Os nomes desses módulos começam com node: para deixar claro que são nativos:
Os que você mais vai usar:
node:fs— ler e escrever arquivos. Usenode:fs/promisespara a versão com async/await.node:path— juntar, resolver e fazer parse de caminhos de arquivo de forma multiplataforma.node:http/node:https— criar servidores HTTP e fazer requisições.node:url— fazer parse e montar URLs.node:os— informações sobre a máquina onde o código está rodando.node:crypto— hashes, bytes aleatórios, criptografia.
Esses não precisam ser instalados. Já vêm junto com o Node. Qualquer outra coisa vem do npm.
O Event Loop do Node.js, em poucas palavras
O Node executa seu JavaScript numa única thread, mas consegue lidar com várias coisas ao mesmo tempo. O segredo está no event loop. Quando você chama algo assíncrono — uma leitura de arquivo, uma requisição HTTP, um timer —, o Node repassa o trabalho de verdade para o sistema operacional (ou para a thread pool interna) e segue executando o resto do código. Quando a tarefa termina, um callback entra na fila, e o loop o processa assim que o código atual acaba de rodar.
A ordem impressa é 1, 4, 2, 3. Primeiro roda o código síncrono. Depois vêm as microtasks (promessas resolvidas). Por último, os timers. É justamente por isso que um loop pesado de CPU trava o servidor inteiro — só existe uma thread para executar o seu código. A concorrência do Node é sobre I/O, não sobre processamento.
Um servidor HTTP minúsculo
A recompensa de entender tudo isso é que um servidor web funcional cabe em poucas linhas:
Sem framework, sem dependências. O createServer recebe uma função que roda a cada requisição; o listen inicia o event loop processando as conexões que chegam. Aplicações reais usam Express ou Fastify por cima disso, mas por baixo é o mesmo módulo http nativo.
Node js vs navegador: o que muda
Vale deixar explícito o que funciona nos dois lados e o que não:
| Funciona nos dois | Só no Node | Só no navegador |
|---|---|---|
Recursos da linguagem (classes, promises, async/await) | fs, http, process, __dirname | window, document, DOM |
console.log | CommonJS require / peculiaridades do ESM no Node | localStorage, sessionStorage |
fetch (Node 18+) | Acesso ao sistema de arquivos e a sockets de rede | Eventos de usuário, renderização |
setTimeout, setInterval | Processos filhos, streams | History API, navigator |
O Node mais recente incorporou várias APIs do navegador — fetch, URL, AbortController, structuredClone — então a distância diminuiu bastante. Mesmo assim, o DOM não vai chegar ao Node, e o sistema de arquivos não vai chegar ao navegador.
Node vs Deno vs Bun
O Node é o padrão, mas já não é o único runtime JavaScript. Deno e Bun são alternativas — o Deno vem do criador original do Node, e o Bun de um time mais novo focado em performance. Todos rodam JavaScript (e TypeScript, de forma nativa), já trazem ferramentas embutidas como test runner e bundler, e se diferenciam do Node em como tratam módulos, permissões e instalação de pacotes.
Para quem está aprendendo JavaScript, o Node continua sendo onde estão a documentação, os tutoriais e as vagas de emprego. Os conceitos — event loop, módulos, APIs nativas — se transferem quase por inteiro para os outros runtimes. Aprenda Node primeiro e adote os outros quando o projeto pedir.
Rodando scripts rapidamente
Algumas formas de executar código de verdade durante o desenvolvimento:
# Executar um arquivo
node script.js
# Executar uma linha de código
node -e "console.log(2 ** 10)"
# Abrir o REPL (prompt interativo)
node
# Observar um arquivo e re-executar ao salvar (Node 18.11+)
node --watch script.js
O REPL é um ótimo rascunho quando você quer ver rapidinho o que um método retorna sem precisar criar um arquivo. Já o --watch salva sua vida no dia a dia do desenvolvimento: você salva o arquivo e o Node reexecuta o script automaticamente.
A seguir: tratando erros
Rodar código é uma coisa. Lidar com ele quando dá ruim é outra história. Leitura de arquivo falha, requisição HTTP estoura o tempo, parse de JSON lança exceção. O próximo capítulo fala justamente sobre try/catch, tipos de erro e os padrões para lidar com o que quebra — porque em um programa Node, mais cedo ou mais tarde, tudo quebra.
Perguntas frequentes
O que é o runtime do Node.js?
Node.js é um programa que executa JavaScript fora do navegador. Ele combina o motor V8 do Google (o mesmo que roda JS no Chrome) com uma camada em C++ que oferece APIs que o V8 sozinho não tem — acesso ao sistema de arquivos, rede, processos e timers. É essa combinação que permite criar servidores, CLIs e ferramentas de build em JavaScript.
Qual a diferença entre Node.js e o navegador?
Os dois rodam JavaScript, mas as APIs em volta da linguagem mudam. No navegador você tem window, document e a DOM. No Node você tem process, fs, http, __dirname e o carregamento de módulos via CommonJS/ESM. Não existe DOM no Node, nem sistema de arquivos no browser — a linguagem é a mesma, a plataforma não.
Node.js é framework ou runtime?
É um runtime. O Node em si não impõe nenhuma estrutura de aplicação — ele só executa JavaScript e expõe APIs. Frameworks como Express, Next.js ou NestJS são construídos em cima do Node. Deno e Bun são runtimes alternativos que concorrem com o Node, mas cumprem o mesmo papel.
O que é o event loop no Node?
O event loop é o que permite o Node lidar com várias coisas ao mesmo tempo usando uma única thread. Quando você chama algo assíncrono — uma leitura de arquivo, uma requisição HTTP, um setTimeout — o Node delega o trabalho para o sistema e continua executando. Quando a operação termina, o callback entra na fila e o event loop o processa. É por isso que fs.readFile não trava o resto do seu programa.