Conventional Commits é uma convenção para dar significado humano e legível por máquinas às mensagens de commit. Em projetos Node.js, ela facilita geração automática de changelogs, cálculo de versões semânticas, revisão de histórico, automação de releases e comunicação entre equipes.
O formato básico é:
tipo(escopo opcional): descrição curta
corpo opcional
rodapés opcionaisUm exemplo:
feat(auth): adiciona login com passkeys
Inclui registro, autenticação e fallback para senha.
Refs: #412Tipos principais
A especificação define efeitos semânticos claros para dois tipos:
fix: correção de bug, normalmente associada a PATCH;feat: nova funcionalidade compatível, normalmente associada a MINOR.
Outros tipos são permitidos:
docs: documentação;test: testes;refactor: mudança interna sem feature ou fix;perf: desempenho;build: sistema de build ou dependências;ci: integração contínua;chore: manutenção;style: formatação sem mudança de comportamento;revert: reversão.
Esses tipos adicionais não implicam versão por si só, salvo quando contêm uma quebra.
Escopo
O escopo identifica a área:
fix(cache): evita expiração duplicada
feat(cli): adiciona comando doctor
docs(api): documenta paginaçãoUse nomes estáveis e reconhecíveis. Em monorepos, o escopo pode representar pacote ou domínio, mas não precisa repetir o nome completo quando isso deixa a mensagem longa.
Descrição curta
A descrição aparece imediatamente após : . Ela deve explicar o resultado, não apenas a ação mecânica. Compare:
chore: mudanças
fix: corrige errocom:
fix(pool): libera conexão após timeout de consultaA segunda mensagem ajuda revisão, changelog e investigação.
Breaking changes
Uma quebra pode ser indicada com !:
feat(api)!: remove resposta legada em XMLOu no rodapé:
feat(config): usa variáveis de ambiente por padrão
BREAKING CHANGE: arquivos locais não sobrescrevem mais variáveis de ambiente.Qualquer tipo pode conter quebra:
refactor(core)!: altera interface do adaptadorFerramentas normalmente traduzem breaking change para MAJOR.
Corpo do commit
O corpo começa após uma linha em branco e fornece contexto:
fix(queue): impede processamento duplicado
O worker agora grava a chave de idempotência antes de confirmar a mensagem.
A mudança evita a janela entre persistência e ACK.Explique motivação, alternativas e efeitos operacionais quando não forem óbvios. Não copie toda a descrição do pull request.
Rodapés
Rodapés seguem estilo semelhante a Git trailers:
Refs: #321
Reviewed-by: Maria
Co-authored-by: João <joao@example.com>BREAKING CHANGE é um token especial. Ferramentas podem interpretar issues, revisores e metadados adicionais.
Commits pequenos e organizados
Uma mensagem convencional não salva um commit que mistura feature, refatoração e atualização de documentação sem relação. Quando possível, divida mudanças por intenção. Isso melhora cherry-pick, revert e bisect.
Evite divisão artificial que gera dezenas de commits impossíveis de compilar. Cada commit deve representar uma unidade coerente e, idealmente, deixar o projeto válido.
Squash merge
Nem todos os contribuidores precisam escrever mensagens perfeitas. Em um fluxo com squash merge, o título final do pull request pode ser validado e usado como commit na branch principal.
Exemplo de política:
- commits internos do PR são livres;
- título do PR segue Conventional Commits;
- squash merge gera um commit convencional;
- release analisa apenas a branch principal.
Commitlint
Instale:
npm install -D @commitlint/cli @commitlint/config-conventionalCrie commitlint.config.mjs:
export default {
extends: ['@commitlint/config-conventional'],
rules: {
'header-max-length': [2, 'always', 72],
'scope-enum': [
2,
'always',
['api', 'cli', 'core', 'deps', 'docs', 'infra'],
],
},
};Teste uma mensagem:
echo "feat(api): adiciona paginação" | npx commitlintHook commit-msg
Com Husky:
npm install -D husky
npx husky initNo hook .husky/commit-msg:
npx --no -- commitlint --edit "$1"Hooks melhoram feedback local, mas podem ser ignorados. O CI deve validar novamente.
Validação no CI
Para validar commits do pull request:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: npm ci
- run: npx commitlint --from origin/main --to HEAD --verboseEm squash workflows, validar o título do PR pode ser mais adequado do que todos os commits intermediários.
Commitizen
Uma interface guiada ajuda iniciantes:
npm install -D commitizen cz-conventional-changelog
Ela pergunta tipo, escopo, descrição e breaking change. A ferramenta reduz erros de sintaxe, mas não substitui uma descrição clara.
Relação com SemVer
O mapeamento comum:
fix→ patch;feat→ minor;BREAKING CHANGEou!→ major.
Tipos como docs, chore e test normalmente não geram release. A ferramenta de automação pode personalizar regras.
Geração de changelog
Ferramentas agrupam commits por tipo e escopo. Porém, mensagens são escritas por desenvolvedores e podem ser técnicas demais para usuários. Revise notas geradas, especialmente em produtos públicos.
Monorepos
Em um monorepo, escopos podem seguir nomes curtos:
feat(logger): adiciona redaction
fix(client): trata retry-after
build(workspaces): atualiza lockfileSe releases são independentes, uma ferramenta precisa descobrir quais pacotes foram afetados. Changesets permite declarar isso explicitamente e pode ser combinado com commits convencionais.
Reverts
Uma convenção possível:
revert: remove cache otimista
Refs: 676104e, a215868O efeito de versão de um revert depende do processo. Reverter uma feature antes da release pode cancelar um minor; depois da release, pode ser um fix. Configure a ferramenta de release.
Dependabot e Renovate
Bots podem criar:
build(deps): atualiza fastify para 5.3.0Atualizações com quebra precisam de revisão e eventualmente !. Não classifique automaticamente toda atualização como patch do seu pacote.
Commits de merge
Merge commits possuem formato próprio e podem ser ignorados por ferramentas. Squash ou rebase produz histórico linear, mas cada equipe deve escolher um modelo consistente.
Política de equipe
Documente:
- tipos permitidos;
- escopos aceitos;
- idioma;
- tamanho do cabeçalho;
- uso de issue;
- regra de breaking change;
- fluxo de squash;
- como commits viram versões.
Erros comuns
- usar
fixpara qualquer mudança; - esquecer breaking change;
- descrições vagas;
- escopos diferentes para a mesma área;
- gerar versão sem revisar changelog;
- validar somente localmente;
- confundir mudança de implementação com efeito ao usuário.
Exemplos úteis
feat(http): adiciona circuit breaker
fix(auth): rejeita refresh token expirado
perf(db): reduz consultas na listagem
test(queue): cobre redelivery após falha
docs(cli): adiciona exemplo de configuração
ci(release): publica proveniência npm
refactor(core)!: remove callbacks da API públicaFluxo recomendado
Defina poucos tipos e escopos, valide títulos de PR ou commits, use squash quando facilitar contribuições e revise releases automáticas. Combine com Changesets no Node.js, Publicação de Pacotes npm, ESLint Flat Config e pipelines em GitHub Actions no Node.js.
Consulte a especificação oficial Conventional Commits 1.0.0 e a documentação oficial do commitlint.



