Uma das maiores vantagens do Node.js não é o que ele faz sozinho — é o que a comunidade construiu em cima dele. O NPM (Node Package Manager) é o maior repositório de código aberto do mundo, com mais de 2 milhões de pacotes disponíveis. Autenticação, envio de email, validação de dados, geração de PDFs, conexão com bancos de dados — existe um pacote para tudo.
Neste artigo você vai aprender a gerenciar dependências com NPM, entender o package.json a fundo, trabalhar com scripts, e adotar boas práticas que fazem diferença em projetos reais.
O que é o NPM
O NPM tem três partes:
1. Registro (registry)
Site: https://npmjs.com
Repositório online com todos os pacotes publicados
2. CLI (command line interface)
Ferramenta de linha de comando instalada com o Node
Comando: npm
3. package.json
Arquivo que descreve seu projeto e suas dependências
Iniciando um projeto
# Cria o package.json interativamente
npm init
# Cria com valores padrão (recomendado para começar rápido)
npm init -y
O package.json gerado:
{
"name": "meu-projeto",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
Instalando pacotes
# Instala e adiciona em "dependencies" (produção)
npm install express
npm install express mongoose dotenv
# Abreviação
npm i express
# Instala e adiciona em "devDependencies" (apenas desenvolvimento)
npm install --save-dev nodemon jest eslint
npm i -D nodemon jest
# Instala globalmente (disponível em qualquer projeto)
npm install -g nodemon
npm install -g typescript
# Instala versão específica
npm install express@4.18.2
# Instala a mais recente de uma versão maior
npm install express@4
# Instala de um repositório GitHub
npm install github:usuario/repositorio
O package.json em profundidade
{
"name": "api-clientes",
"version": "2.1.0",
"description": "API REST para gerenciamento de clientes",
"main": "src/index.js",
"type": "module",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js",
"test": "jest --coverage",
"test:watch": "jest --watch",
"lint": "eslint src/",
"lint:fix": "eslint src/ --fix",
"build": "tsc",
"db:migrate": "node src/db/migrate.js",
"db:seed": "node src/db/seed.js"
},
"dependencies": {
"express": "^4.18.2",
"mongoose": "^7.6.0",
"dotenv": "^16.3.1",
"bcrypt": "^5.1.1",
"jsonwebtoken": "^9.0.2",
"zod": "^3.22.4"
},
"devDependencies": {
"nodemon": "^3.0.2",
"jest": "^29.7.0",
"eslint": "^8.54.0",
"@types/express": "^4.17.21"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=9.0.0"
},
"keywords": ["api", "rest", "express", "mongodb"],
"author": "Ricardo Matos <ricardo@email.com>",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/usuario/api-clientes"
}
}
Versionamento semântico — SemVer
Entender os números de versão é essencial para evitar quebras inesperadas:
MAJOR.MINOR.PATCH
2 . 1 . 0
MAJOR → quebra compatibilidade com versões anteriores
MINOR → adiciona funcionalidade mantendo compatibilidade
PATCH → correção de bug, sem novas funcionalidades
Os prefixos no package.json:
{
"dependencies": {
"express": "4.18.2", // exatamente esta versão
"express": "~4.18.2", // >= 4.18.2, < 4.19.0 (só patches)
"express": "^4.18.2", // >= 4.18.2, < 5.0.0 (minor e patches)
"express": "*", // qualquer versão (perigoso!)
"express": ">=4.0.0", // qualquer versão >= 4
"express": "4.x" // qualquer 4.x.x
}
}
Na prática, ^ (caret) é o padrão — permite updates de minor e patch, mas não de major.
O package-lock.json — reprodutibilidade garantida
# Quando você roda npm install pela primeira vez,
# o NPM cria o package-lock.json
# Este arquivo registra a versão EXATA de cada pacote
# e de cada dependência das dependências (árvore completa)
// package-lock.json (trecho)
{
"name": "meu-projeto",
"version": "1.0.0",
"lockfileVersion": 3,
"packages": {
"node_modules/express": {
"version": "4.18.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
"integrity": "sha512-...",
"dependencies": {
"accepts": "~1.3.8",
"body-parser": "1.20.1"
}
}
}
}
# Instala as versões EXATAS do package-lock.json
# Use em produção e CI/CD para garantir reprodutibilidade
npm ci
# vs npm install → pode atualizar dentro das regras do ^
Regra de ouro: sempre commite o package-lock.json no Git. Nunca commite node_modules.
O node_modules e o .gitignore
# O node_modules pode ter centenas de MB
# NUNCA commite no Git
# .gitignore
node_modules/
.env
.env.local
dist/
build/
*.log
# Para restaurar os node_modules em outro computador:
git clone https://github.com/usuario/projeto
cd projeto
npm install # lê o package.json e restaura tudo
Scripts NPM — automatizando tarefas
Os scripts são um dos recursos mais poderosos do NPM:
{
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js --watch src",
"test": "jest",
"test:coverage": "jest --coverage",
"lint": "eslint .",
"format": "prettier --write .",
"clean": "rm -rf dist node_modules",
"build": "npm run lint && npm run test && node build.js",
"prepublish": "npm run build",
"postinstall": "node scripts/setup.js"
}
}
# Rodar scripts
npm start # convenção para produção
npm test # convenção para testes
npm run dev # scripts customizados precisam de "run"
npm run lint
npm run build
# Hooks automáticos — executam antes/depois
# pre[script] → executa ANTES do script
# post[script] → executa DEPOIS do script
# npm run build → executa: prebuild → build → postbuild
Pacotes essenciais — os que você vai usar sempre
Desenvolvimento:
# Reinicia o servidor automaticamente ao salvar arquivos
npm i -D nodemon
# Linter — encontra problemas no código
npm i -D eslint
# Formatador — padroniza estilo de código
npm i -D prettier
# Framework de testes
npm i -D jest
Produção:
# Framework web
npm i express
# Variáveis de ambiente
npm i dotenv
# Validação de dados
npm i zod
# Hash de senhas
npm i bcrypt
# JWT (autenticação)
npm i jsonwebtoken
# ORM para MongoDB
npm i mongoose
# ORM para SQL
npm i prisma
# Requisições HTTP (alternativa ao fetch nativo)
npm i axios
# Datas e horas
npm i date-fns
dotenv — variáveis de ambiente
Nunca coloque senhas, tokens ou URLs de banco de dados diretamente no código:
# Instalar
npm i dotenv
# .env (nunca commite este arquivo!)
PORT=3000
NODE_ENV=development
DATABASE_URL=mongodb://localhost:27017/meuapp
JWT_SECRET=uma-string-secreta-muito-longa-e-aleatoria
EMAIL_HOST=smtp.gmail.com
EMAIL_USER=meu@email.com
EMAIL_PASS=senha-do-email
// No início da aplicação — antes de tudo
require("dotenv").config();
// ou com ES Modules:
import "dotenv/config";
// Agora process.env tem as variáveis do .env
const porta = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;
const secret = process.env.JWT_SECRET;
if (!dbUrl) {
console.error("❌ DATABASE_URL não definida!");
process.exit(1);
}
console.log(`Rodando em modo: ${process.env.NODE_ENV}`);
# .env.example — versão sem valores reais, ESTE sim vai no Git
PORT=3000
NODE_ENV=development
DATABASE_URL=
JWT_SECRET=
EMAIL_HOST=
EMAIL_USER=
EMAIL_PASS=
nodemon — desenvolvimento ágil
Sem nodemon, você precisaria parar e reiniciar o servidor manualmente a cada mudança:
npm i -D nodemon
// package.json
{
"scripts": {
"dev": "nodemon src/index.js"
}
}
// nodemon.json (configuração opcional)
{
"watch": ["src"],
"ext": "js,json",
"ignore": ["src/tests/**"],
"delay": 500,
"env": {
"NODE_ENV": "development"
}
}
npm run dev
# [nodemon] watching path(s): src/**/*
# [nodemon] starting `node src/index.js`
# Servidor rodando na porta 3000
# (você salva um arquivo...)
# [nodemon] restarting due to changes...
# [nodemon] starting `node src/index.js`
# Servidor rodando na porta 3000
Comandos NPM essenciais
# ── Instalação ───────────────────────────────────
npm install # instala tudo do package.json
npm ci # instala versões exatas do lock
npm i pacote # instala e salva em dependencies
npm i -D pacote # instala e salva em devDependencies
npm i -g pacote # instala globalmente
# ── Remoção ──────────────────────────────────────
npm uninstall pacote # remove e atualiza package.json
npm uninstall -g pacote # remove global
# ── Atualização ──────────────────────────────────
npm update # atualiza tudo (dentro do semver)
npm update pacote # atualiza pacote específico
npm outdated # lista pacotes desatualizados
# ── Informações ──────────────────────────────────
npm list # lista dependências instaladas
npm list --depth=0 # apenas nível 1 (sem transitivas)
npm info pacote # informações do pacote no registry
npm search termo # busca no registry
# ── Auditoria de segurança ────────────────────────
npm audit # verifica vulnerabilidades
npm audit fix # tenta corrigir automaticamente
# ── Cache ─────────────────────────────────────────
npm cache clean --force # limpa o cache
# ── Publicação ───────────────────────────────────
npm login # autentica no registry
npm publish # publica o pacote
npm version patch # incrementa patch (1.0.0 → 1.0.1)
npm version minor # incrementa minor (1.0.0 → 1.1.0)
npm version major # incrementa major (1.0.0 → 2.0.0)
Alternativas ao NPM
# Yarn — criado pelo Facebook, mais rápido no passado
npm i -g yarn
yarn add express
yarn add -D nodemon
yarn install
# pnpm — mais eficiente em espaço em disco
# usa links simbólicos para compartilhar pacotes entre projetos
npm i -g pnpm
pnpm add express
pnpm add -D nodemon
pnpm install
# bun — runtime e gerenciador de pacotes ultra-rápido (2023)
# compatível com NPM
bun add express
bun install
Para projetos novos em 2025, pnpm é uma excelente escolha pela eficiência. NPM ainda é o padrão da indústria e o mais universal.
Exemplo completo — estrutura de projeto profissional
meu-projeto/
├── src/
│ ├── index.js # ponto de entrada
│ ├── config/
│ │ └── index.js # configurações centralizadas
│ ├── routes/ # rotas da API
│ ├── controllers/ # lógica das rotas
│ ├── services/ # regras de negócio
│ ├── models/ # modelos de dados
│ └── utils/ # utilitários
├── tests/ # testes
├── .env # variáveis (não vai no Git)
├── .env.example # modelo (vai no Git)
├── .gitignore
├── .eslintrc.json
├── nodemon.json
├── package.json
└── package-lock.json
// src/config/index.js — configuração centralizada
require("dotenv").config();
const config = {
porta: Number(process.env.PORT) || 3000,
nodeEnv: process.env.NODE_ENV || "development",
dbUrl: process.env.DATABASE_URL,
jwtSecret: process.env.JWT_SECRET,
isDev: process.env.NODE_ENV === "development",
isProd: process.env.NODE_ENV === "production",
isTest: process.env.NODE_ENV === "test",
};
// Valida variáveis obrigatórias
const obrigatorias = ["DATABASE_URL", "JWT_SECRET"];
const faltando = obrigatorias.filter(v => !process.env[v]);
if (faltando.length > 0) {
console.error(`❌ Variáveis de ambiente faltando: ${faltando.join(", ")}`);
process.exit(1);
}
module.exports = config;
Tarefa para você
Crie um projeto Node.js do zero com a seguinte estrutura:
# 1. Inicie o projeto com npm init -y
# 2. Instale as dependências:
# - dotenv (produção)
# - nodemon (dev)
# - date-fns (produção)
# 3. Configure os scripts:
# - start: node src/index.js
# - dev: nodemon src/index.js
# - info: node src/info.js
# 4. Crie src/info.js que imprime:
# - Nome e versão do projeto (lidos do package.json)
# - Data e hora atual formatada com date-fns
# - Variáveis de ambiente: PORT e NODE_ENV
# - Informações do sistema: OS, Node version, memória
# 5. Crie um .env com PORT=3000 e NODE_ENV=development
# 6. Crie um .gitignore adequado
# 7. Crie um .env.example documentado
# Bônus: use o package.json como fonte de verdade
// src/info.js
const pkg = require("../package.json");
console.log(`${pkg.name} v${pkg.version}`);
Conclusão
Neste artigo você aprendeu:
- O que é o NPM e suas três partes — registry, CLI e package.json
- Como iniciar um projeto e instalar pacotes
- O
package.jsonem profundidade — campos, scripts e metadados - Versionamento semântico e os prefixos
^,~e* - A importância do
package-lock.jsonpara reprodutibilidade - Por que nunca commitar
node_modulese como usar.gitignore - Scripts NPM e hooks automáticos
- Os pacotes essenciais do ecossistema Node.js
- Como usar
dotenvpara variáveis de ambiente de forma segura nodemonpara desenvolvimento ágil- Todos os comandos NPM que você vai usar no dia a dia
- Alternativas ao NPM: Yarn, pnpm e bun
- Como estruturar um projeto profissional
📚 Fontes e Referências
- NPM Docs: https://docs.npmjs.com
- NPM Registry: https://npmjs.com
- Semantic Versioning — SemVer: https://semver.org
- dotenv — Documentação: https://github.com/motdotla/dotenv
- nodemon — Documentação: https://nodemon.io
- pnpm — Documentação: https://pnpm.io
- Node.js — package.json fields: https://nodejs.org/en/learn/getting-started/the-package-json-guide
- Node.js Design Patterns — Mario Casciaro (Packt Publishing)
- roadmap.sh — Node.js: https://roadmap.sh/nodejs