Configurar Husky + lint-staged com Claude Code: guia prático de pre-commit
Use Claude Code, Husky e lint-staged para rodar ESLint e Prettier antes de cada commit sem perder velocidade.
Claude Code consegue alterar muitos arquivos em uma única sessão. Isso ajuda em refactors, testes e ajustes de configuração, mas também aumenta o ruído da revisão. A pessoa revisora deveria focar em comportamento, arquitetura e riscos, não em imports sem uso, formatação inconsistente ou quebras de linha em Markdown.
Husky + lint-staged resolve uma parte objetiva desse problema. Um Git hook é um pequeno script executado pelo Git em um ponto do fluxo, como antes de criar um commit. Husky permite versionar esses hooks dentro do repositório. lint-staged executa comandos apenas nos arquivos que já estão preparados com git add, evitando varrer o projeto inteiro a cada commit. Hooks do Claude Code são outra camada: eles rodam dentro do ciclo de vida do Claude Code. São úteis como apoio, mas não substituem um Git hook que protege qualquer commit.
A meta não é criar um CI local pesado. O desenho que funciona melhor é: checks rápidos em pre-commit, validações médias em pre-push e verificação completa em CI.
Fluxo recomendado
Quando Claude Code muda vários arquivos, a automação precisa ser previsível. Primeiro o desenvolvedor escolhe o que vai entrar com git add; depois Husky chama lint-staged; então ESLint e Prettier atuam apenas nesses arquivos.
flowchart LR
A["Claude Code edita arquivos"] --> B["Desenvolvedor faz git add"]
B --> C["Husky pre-commit"]
C --> D["lint-staged"]
D --> E["ESLint / Prettier"]
E --> F["commit"]
C --> G["typecheck, testes e build ficam em pre-push ou CI"]
As referências oficiais usadas aqui são Husky Get started, lint-staged README, manual de Git hooks e Claude Code hooks reference. O detalhe prático é que Husky recomenda npx husky init, e lint-staged precisa de um hook pre-commit mais uma configuração de padrões de arquivos.
Configuração mínima
Se ESLint ou Prettier ainda não estão estáveis no projeto, comece pelo guia de ESLint com Claude Code e pelo guia de Prettier. Husky apenas dispara comandos; ele não conserta regras mal definidas.
Um prompt útil para Claude Code deve deixar claro o escopo:
Adicione Husky e lint-staged a este repositório Node.js/TypeScript.
O pre-commit deve processar apenas arquivos JS, TS, JSON, Markdown e CSS staged.
Rode ESLint com auto-fix e Prettier no pre-commit.
Não coloque typecheck, testes nem build no pre-commit; mova isso para pre-push ou CI.
No fim, liste os comandos de verificação manual.
Instalando manualmente:
npm install --save-dev husky lint-staged eslint prettier
npx husky init
npx husky init cria .husky/pre-commit e atualiza o script prepare no package.json. Troque o conteúdo do hook por:
#!/usr/bin/env sh
npx lint-staged
Depois adicione a configuração. Se já existirem scripts no package.json, faça merge das chaves em vez de substituir tudo.
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"format": "prettier --write .",
"format:check": "prettier --check .",
"prepare": "husky"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix --max-warnings=0",
"prettier --write"
],
"*.{json,md,mdx,yml,yaml,css,scss}": [
"prettier --write"
]
}
}
Para testar, crie um arquivo com formatação ruim e prepare-o:
git add src/example.ts
npx lint-staged --debug
git commit -m "chore: verify pre-commit checks"
--debug mostra qual configuração foi carregada, quais arquivos casaram com cada glob e quais comandos rodaram. Se algo falhar, envie essa saída para Claude Code junto com a pergunta.
Configuração sustentável
Em repositórios maiores, prefiro mover a configuração para lint-staged.config.mjs. O package.json fica mais legível e podemos usar pequenas funções auxiliares. Este exemplo coloca aspas nos caminhos para reduzir problemas com nomes de arquivo que têm espaço.
// lint-staged.config.mjs
const shellQuote = (file) => `"${file.replaceAll('"', '\\"')}"`;
const joinFiles = (files) => files.map(shellQuote).join(" ");
export default {
"*.{js,jsx,ts,tsx}": (files) => [
`eslint --fix --max-warnings=0 ${joinFiles(files)}`,
`prettier --write ${joinFiles(files)}`,
],
"*.{json,md,mdx,yml,yaml,css,scss}": (files) =>
`prettier --write ${joinFiles(files)}`,
};
Ao usar esse arquivo, remova a chave lint-staged de package.json. Duas fontes de verdade criam divergência e confundem tanto humanos quanto Claude Code.
Três casos de uso
Primeiro caso: uma aplicação TypeScript. Claude Code costuma alterar componentes, testes e utilitários juntos. ESLint com auto-fix e Prettier removem ruído antes da revisão. Typecheck completo precisa do contexto do projeto, então é melhor em pre-push ou CI.
Segundo caso: um site Astro ou Next.js com bastante conteúdo. MDX, JSON, CSS e TypeScript mudam ao mesmo tempo. lint-staged mantém o diff focado no conteúdo real, sem misturar revisão editorial com espaços e quebras de linha.
Terceiro caso: monorepo. Rodar todos os testes de todos os pacotes em pre-commit costuma ficar lento. Formate e aplique lint nos arquivos staged, depois deixe CI ou o task runner escolher os testes relevantes pelos caminhos alterados.
commit-msg e pre-push
Regras de mensagem de commit devem ficar em um hook separado. Para Conventional Commits, use commitlint.
npm install --save-dev @commitlint/cli @commitlint/config-conventional
// commitlint.config.mjs
export default {
extends: ["@commitlint/config-conventional"],
rules: {
"subject-max-length": [2, "always", 72],
},
};
#!/usr/bin/env sh
npx --no -- commitlint --edit "$1"
Coloque esse shell em .husky/commit-msg. Para checks mais pesados, use .husky/pre-push:
#!/usr/bin/env sh
npm run validate
O script validate pode espelhar CI:
{
"scripts": {
"typecheck": "tsc --noEmit",
"test:ci": "vitest run --coverage",
"build": "vite build",
"validate": "npm run typecheck && npm run lint && npm run format:check && npm run test:ci && npm run build"
}
}
Armadilhas comuns
A maior armadilha é deixar pre-commit pesado demais. Se cada commit demora dois minutos, a equipe aprende a pular o hook. Se dura poucos segundos, ele vira hábito.
Outra armadilha é o partial staging. lint-staged olha para arquivos staged, mas o mesmo arquivo pode ter mudanças não staged. Para depurar, veja git status --short, git diff --staged e npx lint-staged --debug juntos.
Em equipes com Windows, macOS e Linux, finais de linha importam. Hooks do Husky são scripts shell, então LF é a opção mais segura.
* text=auto eol=lf
*.cmd text eol=crlf
*.bat text eol=crlf
Também evite || true. Isso esconde falhas e transforma a barreira de qualidade em enfeite. Peça ao Claude Code para reduzir o erro, mover tarefas lentas para pre-push ou documentar o comando de correção.
Resultado testado
Testei essa estrutura em um projeto TypeScript/Vite pequeno com formatação quebrada, import sem uso e problema de espaço em MDX. pre-commit ficou rápido porque processou apenas arquivos staged. npx lint-staged --debug deixou claro quais arquivos e comandos estavam envolvidos. Erros de tipo ficaram para npm run validate no pre-push, preservando o ritmo de commits sem perder a proteção final.
Resumo
Husky + lint-staged é uma proteção prática para fluxos com Claude Code. Mantenha pre-commit leve, mova verificações caras para pre-push ou CI e descreva essa separação nos prompts. Assim o hook vira um padrão de qualidade compartilhado, não um obstáculo local.
O próximo passo é reforçar as regras no guia de ESLint e padronizar formatação com o guia de Prettier.
PDF grátis: cheatsheet do Claude Code
Informe seu e-mail e baixe uma página com comandos, hábitos de revisão e workflows seguros.
Cuidamos dos seus dados e não enviamos spam.
Sobre o autor
Masa
Engenheiro focado em workflows práticos com Claude Code.
Artigos relacionados
Escada de segurança de permissões no Claude Code
Amplie de read-only para edições limitadas, comandos de prova e deploy checks sem perder controle.
Claude Code Small PR Proof Pack: pequenas mudanças fáceis de revisar
Um pacote de prova para PRs do Claude Code: diff, checks, URL pública, CTA e rollback.
Gate de revisão antes do commit com Claude Code
Revisão antes do commit com Claude Code: diff, build, URL pública, Gumroad, consultoria, testes e arquivos fora do escopo.