Até agora todo o JavaScript que escrevemos rodou no navegador. O navegador é um ambiente rico — tem o DOM, eventos, LocalStorage, APIs de geolocalização. Mas ele tem uma limitação fundamental: só existe dentro de uma aba.
O Node.js quebrou essa barreira em 2009. Pela primeira vez, JavaScript podia rodar no servidor — lendo arquivos do disco, abrindo conexões de rede, criando APIs, acessando bancos de dados. A mesma linguagem que você usa no front-end, agora também no back-end.
Este artigo apresenta o Node.js do zero — o que é, como funciona, o que muda em relação ao navegador e como dar os primeiros passos.
O que é Node.js?
Node.js é um ambiente de execução JavaScript construído sobre o motor V8 do Chrome. Não é uma linguagem nova — é JavaScript. O que muda é o ambiente onde ele roda e as APIs disponíveis.
┌──────────────────────────────────────────────────────┐
│ COMPARATIVO │
│ │
│ NAVEGADOR NODE.JS │
│ ───────────────────────── ────────────────── │
│ Motor: V8 (Chrome) Motor: V8 │
│ DOM, window, document Sem DOM │
│ fetch, localStorage Módulos nativos │
│ alert, confirm fs, path, os, http │
│ Limitado ao sandbox Acesso total ao OS │
│ Roda na aba do usuário Roda no servidor │
│ Distribuído ao cliente Fica no servidor │
└──────────────────────────────────────────────────────┘
Instalando e verificando o Node.js
# Verificar se já está instalado
node --version # ex: v20.11.0
npm --version # ex: 10.2.4
# Instalar (se necessário): https://nodejs.org
# Recomendado: versão LTS (Long Term Support)
Seu primeiro programa Node.js
Crie um arquivo ola.js:
// ola.js
console.log("Olá, Node.js!");
console.log("Versão:", process.version);
console.log("Sistema:", process.platform);
console.log("Diretório atual:", process.cwd());
Execute no terminal:
node ola.js
# Olá, Node.js!
# Versão: v20.11.0
# Sistema: linux
# Diretório atual: /home/usuario/projetos
Sem navegador. Sem HTML. Só JavaScript rodando direto no sistema operacional.
O objeto process — a ponte com o sistema
No navegador temos window. No Node, temos process:
// Informações do ambiente
console.log(process.version); // versão do Node
console.log(process.platform); // "linux", "win32", "darwin"
console.log(process.arch); // "x64", "arm64"
console.log(process.cwd()); // diretório de trabalho atual
console.log(process.env.HOME); // variáveis de ambiente
console.log(process.pid); // ID do processo
// Argumentos passados na linha de comando
// node script.js arg1 arg2
console.log(process.argv);
// ["node", "/path/script.js", "arg1", "arg2"]
const args = process.argv.slice(2); // remove "node" e o nome do arquivo
console.log(args); // ["arg1", "arg2"]
// Encerrar o processo
process.exit(0); // 0 = sucesso
process.exit(1); // 1 = erro
Sistema de módulos — CommonJS vs ES Modules
Node.js suporta dois sistemas de módulos. Entender a diferença é fundamental:
// ── CommonJS (padrão histórico do Node) ──────────
// Arquivos .js usam require() e module.exports
// matematica.js
function somar(a, b) { return a + b; }
function multiplicar(a, b) { return a * b; }
module.exports = { somar, multiplicar };
// ou exportar um por um:
module.exports.somar = somar;
// app.js
const { somar, multiplicar } = require("./matematica");
console.log(somar(3, 4)); // 7
console.log(multiplicar(3, 4)); // 12
// Módulos nativos do Node
const fs = require("fs");
const path = require("path");
const os = require("os");
// ── ES Modules (moderno, recomendado) ────────────
// Arquivos .mjs OU "type": "module" no package.json
// matematica.mjs
export function somar(a, b) { return a + b; }
export function multiplicar(a, b) { return a * b; }
export default { somar, multiplicar };
// app.mjs
import { somar, multiplicar } from "./matematica.mjs";
import fs from "fs";
Para novos projetos, prefira ES Modules. Para código legado e muitas bibliotecas, você ainda encontrará CommonJS.
Módulo fs — trabalhando com arquivos
O módulo fs (file system) é um dos mais usados no Node:
const fs = require("fs");
const path = require("path");
// ── Leitura ─────────────────────────────────────
// Síncrono — bloqueia a thread (evitar em servidores)
const conteudo = fs.readFileSync("arquivo.txt", "utf-8");
console.log(conteudo);
// Assíncrono com callback
fs.readFile("arquivo.txt", "utf-8", (erro, conteudo) => {
if (erro) {
console.error("Erro ao ler:", erro.message);
return;
}
console.log(conteudo);
});
// Assíncrono com Promise (recomendado)
const fsPromises = require("fs").promises;
// ou: const { readFile } = require("fs/promises");
async function lerArquivo(caminho) {
try {
const conteudo = await fsPromises.readFile(caminho, "utf-8");
return conteudo;
} catch (erro) {
if (erro.code === "ENOENT") {
throw new Error(`Arquivo não encontrado: ${caminho}`);
}
throw erro;
}
}
// ── Escrita ─────────────────────────────────────
// Sobrescreve o arquivo (cria se não existir)
await fsPromises.writeFile("saida.txt", "Olá, arquivo!", "utf-8");
// Adiciona ao final sem apagar o conteúdo existente
await fsPromises.appendFile("log.txt", `${new Date().toISOString()} — evento
`);
// ── Operações de diretório ───────────────────────
// Criar diretório (recursive: cria diretórios pais também)
await fsPromises.mkdir("pasta/subpasta", { recursive: true });
// Listar arquivos
const arquivos = await fsPromises.readdir("./");
console.log(arquivos);
// Verificar se existe
try {
await fsPromises.access("arquivo.txt");
console.log("Existe!");
} catch {
console.log("Não existe.");
}
// Informações do arquivo
const stats = await fsPromises.stat("arquivo.txt");
console.log(`Tamanho: ${stats.size} bytes`);
console.log(`Modificado: ${stats.mtime}`);
console.log(`É diretório: ${stats.isDirectory()}`);
// Renomear / mover
await fsPromises.rename("antigo.txt", "novo.txt");
// Deletar
await fsPromises.unlink("arquivo.txt");
await fsPromises.rm("pasta", { recursive: true }); // pasta com conteúdo
Módulo path — trabalhando com caminhos
Caminhos de arquivo são diferentes em Windows () e Unix (/). O módulo path resolve isso:
const path = require("path");
// Construir caminhos de forma segura (multiplataforma)
const caminho = path.join("/usuarios", "ana", "documentos", "arquivo.txt");
// "/usuarios/ana/documentos/arquivo.txt" no Unix
// "\usuarios\ana\documentos\arquivo.txt" no Windows
// Caminho absoluto a partir de caminho relativo
const absoluto = path.resolve("pasta", "arquivo.txt");
// "/projeto/atual/pasta/arquivo.txt"
// Partes do caminho
console.log(path.dirname("/pasta/subpasta/arquivo.txt")); // "/pasta/subpasta"
console.log(path.basename("/pasta/arquivo.txt")); // "arquivo.txt"
console.log(path.basename("/pasta/arquivo.txt", ".txt")); // "arquivo"
console.log(path.extname("/pasta/arquivo.txt")); // ".txt"
// __dirname e __filename (CommonJS) — diretório e arquivo atual
console.log(__dirname); // "/home/usuario/projeto"
console.log(__filename); // "/home/usuario/projeto/app.js"
// Equivalente em ES Modules
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Módulo os — informações do sistema operacional
const os = require("os");
console.log(os.platform()); // "linux", "darwin", "win32"
console.log(os.arch()); // "x64", "arm64"
console.log(os.hostname()); // nome do computador
console.log(os.homedir()); // "/home/usuario"
console.log(os.tmpdir()); // "/tmp"
console.log(os.cpus().length); // número de CPUs
// Memória
const totalMem = os.totalmem();
const livMem = os.freemem();
console.log(`Memória total: ${(totalMem / 1024 / 1024 / 1024).toFixed(1)} GB`);
console.log(`Memória livre: ${(livMem / 1024 / 1024 / 1024).toFixed(1)} GB`);
console.log(`Uso: ${Math.round((1 - livMem / totalMem) * 100)}%`);
// Uptime
console.log(`Sistema rodando há ${Math.floor(os.uptime() / 3600)} horas`);
Um script prático — processador de arquivos
Vamos construir um script real que lê um arquivo CSV, processa os dados e gera um relatório:
// relatorio.js
const fs = require("fs/promises");
const path = require("path");
// Dados de exemplo — normalmente lidos de um arquivo real
const csvExemplo = `nome,departamento,salario,ativo
Ana Paula,Engenharia,8500,true
Carlos Silva,Design,6200,true
Beatriz Costa,Engenharia,9100,false
Diego Mendes,Marketing,5800,true
Elena Souza,Engenharia,7700,true
Fernando Lima,Design,6800,false
Gabriela Ramos,Marketing,5500,true
Hugo Santos,Engenharia,10200,true`;
function parsearCSV(texto) {
const linhas = texto.trim().split("
");
const cabecalho = linhas[0].split(",");
return linhas.slice(1).map(linha => {
const valores = linha.split(",");
return cabecalho.reduce((obj, col, i) => {
const val = valores[i]?.trim();
// Conversão de tipos
if (val === "true") obj[col] = true;
else if (val === "false") obj[col] = false;
else if (!isNaN(val) && val !== "") obj[col] = Number(val);
else obj[col] = val;
return obj;
}, {});
});
}
function gerarRelatorio(funcionarios) {
const ativos = funcionarios.filter(f => f.ativo);
const inativos = funcionarios.filter(f => !f.ativo);
// Agrupamento por departamento
const porDepartamento = funcionarios.reduce((acc, f) => {
if (!acc[f.departamento]) {
acc[f.departamento] = { funcionarios: [], totalSalario: 0 };
}
acc[f.departamento].funcionarios.push(f);
acc[f.departamento].totalSalario += f.salario;
return acc;
}, {});
const totalSalarios = ativos.reduce((acc, f) => acc + f.salario, 0);
const mediaSalarial = totalSalarios / ativos.length;
const maiorSalario = Math.max(...funcionarios.map(f => f.salario));
const menorSalario = Math.min(...funcionarios.map(f => f.salario));
const separador = "═".repeat(50);
let relatorio = `
${separador}
RELATÓRIO DE RECURSOS HUMANOS
Gerado em: ${new Date().toLocaleString("pt-BR")}
${separador}
📊 RESUMO GERAL
${"─".repeat(50)}
Total de funcionários : ${funcionarios.length}
Funcionários ativos : ${ativos.length}
Funcionários inativos : ${inativos.length}
Folha de pagamento : R$ ${totalSalarios.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}
Salário médio : R$ ${mediaSalarial.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}
Maior salário : R$ ${maiorSalario.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}
Menor salário : R$ ${menorSalario.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}
🏢 POR DEPARTAMENTO
${"─".repeat(50)}`;
Object.entries(porDepartamento)
.sort((a, b) => b[1].totalSalario - a[1].totalSalario)
.forEach(([depto, dados]) => {
const media = dados.totalSalario / dados.funcionarios.length;
relatorio += `
${depto}
Funcionários : ${dados.funcionarios.length}
Total folha : R$ ${dados.totalSalario.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}
Média salarial: R$ ${media.toLocaleString("pt-BR", { minimumFractionDigits: 2 })}
Membros: ${dados.funcionarios.map(f => f.nome.split(" ")[0]).join(", ")}
`;
});
relatorio += `
👥 LISTA DE FUNCIONÁRIOS
${"─".repeat(50)}
${"Nome".padEnd(20)} ${"Depto".padEnd(12)} ${"Salário".padEnd(12)} Status`;
relatorio += "
" + "─".repeat(50);
funcionarios
.sort((a, b) => b.salario - a.salario)
.forEach(f => {
const status = f.ativo ? "✅ Ativo" : "❌ Inativo";
const salario = `R$ ${f.salario.toLocaleString("pt-BR")}`;
relatorio += `
${f.nome.padEnd(20)} ${f.departamento.padEnd(12)} ${salario.padEnd(12)} ${status}`;
});
relatorio += `
${separador}
`;
return relatorio;
}
async function main() {
// Argumentos da linha de comando
const args = process.argv.slice(2);
const arquivoEntrada = args[0] || null;
const arquivoSaida = args[1] || "relatorio.txt";
let csvTexto;
if (arquivoEntrada) {
console.log(`📂 Lendo arquivo: ${arquivoEntrada}`);
csvTexto = await fs.readFile(arquivoEntrada, "utf-8");
} else {
console.log("📝 Usando dados de exemplo...");
csvTexto = csvExemplo;
}
const funcionarios = parsearCSV(csvTexto);
console.log(`✅ ${funcionarios.length} funcionários carregados.`);
const relatorio = gerarRelatorio(funcionarios);
// Exibe no console
console.log(relatorio);
// Salva em arquivo
const caminhoSaida = path.resolve(arquivoSaida);
await fs.writeFile(caminhoSaida, relatorio, "utf-8");
console.log(`💾 Relatório salvo em: ${caminhoSaida}`);
}
main().catch(erro => {
console.error("❌ Erro fatal:", erro.message);
process.exit(1);
});
Execute:
node relatorio.js
# ou com arquivo real:
node relatorio.js funcionarios.csv relatorio.txt
REPL — o terminal interativo do Node
# Inicia o REPL (Read-Eval-Print Loop)
node
# Agora você pode digitar JavaScript diretamente:
> 2 + 2
4
> const nome = "Ana"
undefined
> `Olá, ${nome}!`
'Olá, Ana!'
> [1,2,3].map(n => n * 2)
[ 2, 4, 6 ]
> .exit # ou Ctrl+D para sair
Ótimo para testar código rapidamente sem criar arquivos.
O que Node.js tem que o navegador não tem
// Acesso ao sistema de arquivos
const fs = require("fs/promises");
await fs.readFile("/etc/hostname");
// Variáveis de ambiente (segredos, configurações)
const dbUrl = process.env.DATABASE_URL;
const porta = process.env.PORT || 3000;
// Informações do processo
process.pid; // ID do processo
process.memoryUsage(); // uso de memória
process.uptime(); // tempo rodando
// Criação de processos filhos
const { exec } = require("child_process");
exec("ls -la", (erro, stdout) => console.log(stdout));
// Servidor TCP/HTTP nativo
const http = require("http");
const servidor = http.createServer((req, res) => {
res.end("Olá!");
});
servidor.listen(3000);
// Streams — processamento de dados em fluxo
const readable = fs.createReadStream("arquivo-grande.txt");
readable.on("data", chunk => processar(chunk));
O que o navegador tem que Node não tem
// ❌ Não existe no Node.js:
document.querySelector("#btn");
window.localStorage;
window.alert("mensagem");
fetch("url"); // existe, mas só no Node 18+
navigator.geolocation;
Boas práticas ao começar com Node.js
# ✅ 1. Sempre crie um package.json no início do projeto
npm init -y
# ✅ 2. Use .env para variáveis sensíveis
# Crie um arquivo .env
# PORT=3000
# DATABASE_URL=postgres://...
# ✅ 3. Nunca commite .env no Git
# Adicione ao .gitignore:
echo ".env" >> .gitignore
echo "node_modules" >> .gitignore
# ✅ 4. Use versão LTS do Node
node --version # deve começar com número par: v20, v22...
// ✅ 5. Trate erros de processo
process.on("uncaughtException", (erro) => {
console.error("Erro não capturado:", erro);
process.exit(1);
});
process.on("unhandledRejection", (erro) => {
console.error("Promise rejeitada não tratada:", erro);
process.exit(1);
});
// ✅ 6. Prefira fs/promises em vez de fs com callbacks
// ❌ Evitar
fs.readFile("arquivo.txt", "utf-8", callback);
// ✅ Prefira
const conteudo = await fsPromises.readFile("arquivo.txt", "utf-8");
// ✅ 7. Use path.join para construir caminhos
// ❌ Evitar
const caminho = __dirname + "/pasta/" + arquivo;
// ✅ Prefira
const caminho = path.join(__dirname, "pasta", arquivo);
Tarefa para você
Construa um script de backup em Node.js que:
1. Lê todos os arquivos .txt e .json de um diretório
2. Cria um diretório "backup/YYYY-MM-DD" com a data atual
3. Copia todos os arquivos para o backup
4. Gera um arquivo "manifesto.json" no backup com:
- nome de cada arquivo
- tamanho em bytes
- data de modificação
- hash MD5 do conteúdo (use o módulo crypto nativo)
5. Exibe um resumo no terminal:
- Quantos arquivos copiados
- Tamanho total do backup
- Caminho do diretório de backup
// Dica — módulo crypto para MD5:
const crypto = require("crypto");
const hash = crypto.createHash("md5").update(conteudo).digest("hex");
Conclusão
Neste artigo você aprendeu:
- O que é o Node.js e como ele difere do navegador
- O objeto
processe seu papel no ambiente Node - CommonJS vs ES Modules — os dois sistemas de módulos
- O módulo
fspara leitura, escrita e manipulação de arquivos - O módulo
pathpara trabalhar com caminhos de forma multiplataforma - O módulo
ospara informações do sistema operacional - Como construir scripts práticos com argumentos e saída em arquivo
- O REPL para testes rápidos no terminal
- As diferenças entre o ambiente Node e o navegador
- Boas práticas desde o início
📚 Fontes e Referências
- Node.js Official Docs: https://nodejs.org/en/docs
- Node.js — fs module: https://nodejs.org/api/fs.html
- Node.js — path module: https://nodejs.org/api/path.html
- Node.js — os module: https://nodejs.org/api/os.html
- Node.js — process object: https://nodejs.org/api/process.html
- JavaScript.info — Node.js: https://javascript.info/nodejs
- Node.js Design Patterns — Mario Casciaro (Packt Publishing)
- Learning Node.js Development — Andrew Mead (Packt Publishing)
- roadmap.sh — Node.js Roadmap: https://roadmap.sh/nodejs