Tips & Tricks (Atualizado: 02/06/2026)

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.

Configurar Husky + lint-staged com Claude Code: guia prático de pre-commit

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.

#Claude Code #Husky #lint-staged #Git hooks #qualidade de codigo
Grátis

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.

Masa

Sobre o autor

Masa

Engenheiro focado em workflows práticos com Claude Code.