Recentemente precisei revisitar a forma como estávamos gerenciando os Git hooks em um dos projetos do time. Nada estava exatamente “quebrado”. O Husky estava funcionando, os hooks rodavam, o lint acontecia antes do commit e os testes antes do push. Mas tinham dois pontos incomodando: o tempo de execução e ajustes específicos para funcionar em windows, linux e mac.
Pre-commits começando a demorar mais do que deveriam, scripts rodando de forma sequencial e pequenas esperas que, no dia a dia, acabam se acumulando. Não era um problema crítico, mas era aquele tipo de fricção que todo desenvolvedor percebe: você faz um commit pequeno e fica alguns segundos olhando para o terminal esperando os hooks terminarem.
Foi aí que comecei a investigar alternativas para melhorar esse fluxo. Durante essa busca, encontrei o Lefthook, uma ferramenta para gerenciamento de Git hooks escrita em Go, com foco em performance e execução paralela.
Resolvi então fazer um experimento prático: migrar a configuração do projeto de Husky para Lefthook, medir os impactos e entender se a mudança realmente valeria a pena.
Este post mostra exatamente esse processo: o que motivou a mudança, como foi feita a migração e quais foram os resultados na prática.
1. Melhor Performance
-
Lefthook é mais rápido: Lefthook é escrito em Go, uma linguagem compilada e eficiente, o que o torna significativamente mais rápido que o Husky, que é baseado em JavaScript. Isso é especialmente notável em projetos grandes com múltiplos hooks, onde o tempo de execução dos hooks pode impactar a produtividade.
-
Execução paralela de hooks: Lefthook suporta a execução paralela dos hooks, permitindo que várias tarefas rodem simultaneamente, reduzindo o tempo total de pre-commit ou pre-push. Husky executa hooks sequencialmente, o que pode aumentar o tempo de espera quando há muitos scripts para rodar.
2. Configuração Mais Simples e Flexível
-
Configuração via YAML: Lefthook utiliza um arquivo de configuração YAML (lefthook.yml), que é mais legível e flexível para definir hooks complexos e múltiplos comandos. Husky usa configuração no package.json ou scripts que podem ficar confusos em projetos maiores.
-
Independência do Node.js: Lefthook é agnóstico em relação à linguagem, funcionando bem em projetos que não são baseados em JavaScript/Node.js, enquanto Husky está fortemente integrado ao ecossistema Node.js. Isso torna Lefthook uma escolha melhor para projetos multi-linguagem ou que usam outras stacks.
-
Manutenção do package.json mais limpa: Lefthook não adiciona dependências ou scripts extras no package.json, mantendo o arquivo mais organizado, o que facilita o gerenciamento em equipes e ambientes de CI/CD.
3. Facilidade na Migração e Uso
-
A migração do Husky para Lefthook é simples e rápida, podendo ser feita com poucos comandos, como desinstalar Husky e instalar Lefthook, além de mover a configuração para o arquivo YAML, sem grande impacto no fluxo atual.
-
Lefthook possui uma CLI amigável para gerenciar e testar hooks manualmente, o que ajuda na configuração e depuração.
4. Suporte Multiplataforma e Comunidade
-
Lefthook oferece suporte nativo a Windows, Linux e macOS, garantindo compatibilidade em diferentes ambientes de desenvolvimento.
-
Embora Husky tenha uma comunidade maior atualmente, Lefthook vem ganhando espaço e possui documentação clara e atualizações regulares, com suporte ativo no GitHub
Comparativo Técnico: Husky vs Lefthook
| Aspecto | Husky | Lefthook |
|---|---|---|
| Linguagem | JavaScript (Node.js) | Go (agnóstico) |
| Performance | Sequencial, mais lento | Paralelo, mais rápido |
| Configuração | JSON no package.json | YAML (mais legível e flexível) |
| Suporte a múltiplas linguagens | Limitado ao Node.js | Completo, multi-stack |
| Suporte multiplataforma | Sim | Sim |
| Impacto no package.json | Adiciona dependências | Mantém package.json limpo |
| Integração com CI/CD | Requer configuração manual | Automatizado e padronizável |
| Facilidade de migração | N/A | Simples e rápida |
| Suporte a monorepos | Limitado | Nativo |
| Comunidade | Grande e consolidada | Menor, mas crescente |
| Curva de aprendizado | Média | Baixa |
Comparação prática em um projeto demo
- Lefthook executando todos os hooks em 10.72seg
- O Eslint ainda é o que leva mais tempo e há espaço para otimização e um futuro ajuste. Talvez implementar cache para eslint

- O Eslint ainda é o que leva mais tempo e há espaço para otimização e um futuro ajuste. Talvez implementar cache para eslint
- Husky executando apenas lint em 14.96s.

Comparativo de Performance na prática
Durante testes no projeto, observamos uma diferença significativa no tempo de execução dos Git hooks entre Husky e Lefthook:
| Ferramenta | Hooks executados | Tempo total |
|---|---|---|
| Husky | Apenas Lint | 14.96s |
| Lefthook | Lint + Prettier + Console.log | 10.72s |
Mesmo executando mais tarefas, o Lefthook foi 28.3% mais rápido que o Husky.
Essa diferença representa um ganho de 4.24 segundos em um cenário com apenas 3 arquivos modificados. Em cenários com mais arquivos ou em times maiores, o impacto acumulado pode ser ainda mais significativo.
Como o Lefthook executa os hooks em paralelo, o tempo total tende a crescer menos conforme aumenta a quantidade de arquivos, proporcionando melhor escalabilidade e eficiência no fluxo de trabalho.
Benefícios Esperados
-
Redução significativa no tempo de execução dos hooks, aumentando a produtividade.
-
Configuração mais simples e organizada, facilitando a manutenção e onboarding de novos colaboradores.
-
Maior flexibilidade para projetos que utilizam múltiplas linguagens.
-
Arquivo package.json mais limpo e fácil de gerenciar.
Impactos e Riscos
-
Curva de aprendizado inicial para a equipe se familiarizar com Lefthook.
-
Necessidade de atualização dos scripts e configuração dos hooks.
-
Risco mínimo de incompatibilidade, mitigado por testes prévios.
Guia de migração
1. Configuração do Lefthook (lefthook.yml)
- Configuração otimizada para o projeto
- Hooks configurados:
commit-msg,pre-commit,pre-push - Execução paralela habilitada para melhor performance
- Auto-staging de arquivos corrigidos (
stage_fixed: true) - Verificação de console.log esquecidos
2. Package.json
- Script
preparealterado dehusky installparalefthook install
3. Commitlint Configuration
- Configuração simplificada com regras padrão do conventional commits
4. Utilização do diretório .husky
Os arquivos referentes aos git hooks foram gerados automaticamente pelo lefthook reaproveitando o diretório .husky por padrão da ferramenta.
Comandos Executados nos Hooks
commit-msg
yarn commitlint --edit .git/COMMIT_EDITMSG
pre-commit (execução paralela)
- lint:
yarn eslint {staged_files} --fix- Arquivos:
{src,apps,libs,test}/**/*.{ts,tsx} - Auto-staging habilitado
- Arquivos:
- format:
yarn prettier --write {staged_files}- Arquivos:
{src,apps,libs,test}/**/*.{ts,tsx} - Auto-staging habilitado
- Arquivos:
- no-console: Verificação de console.log esquecidos
- Arquivos:
{src,apps,libs,test}/**/*.{ts,tsx} - Bloqueia commit se encontrar
console.
- Arquivos:
pre-push (execução paralela)
- test:
yarn test:cov:local
Otimizações Implementadas
Performance
- Execução paralela:
parallel: truenos hookspre-commitepre-push - Auto-staging:
stage_fixed: truepara lint e format - Globs específicos: Apenas arquivos TypeScript/TSX relevantes
Qualidade de Código
- ESLint com auto-fix: Corrige problemas automaticamente
- Prettier: Formatação consistente
- Console detection: Previne console.log em produção
- Testes com coverage: Garante qualidade antes do push
Instalação
Para instalar os hooks do Lefthook:
yarn lefthook installVerificação
Para verificar se os hooks estão funcionando:
# Testar commitlint
echo "feat: test commit message" | yarn commitlint
# Testar hooks individualmente
yarn lefthook run commit-msg
yarn lefthook run pre-commit
yarn lefthook run pre-push
# Verificar configuração
yarn lefthook versionRegras do Commitlint
O projeto agora usa as regras padrão do conventional commits:
- Tipos permitidos: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert
- Header máximo: 140 caracteres
- Body máximo por linha: 280 caracteres
Conclusão
No fim das contas, essa migração começou como um experimento simples: entender se existia uma forma mais eficiente de executar os Git hooks no projeto.
A troca do Husky pelo Lefthook acabou trazendo alguns benefícios claros. A execução paralela reduz significativamente o tempo total dos hooks, a configuração em YAML deixa a estrutura mais organizada e a independência do Node.js torna a ferramenta mais flexível para diferentes stacks.
Na prática, a diferença mais perceptível está na experiência do desenvolvedor. Quando os hooks executam mais rápido, o fluxo de commit fica mais fluido e a fricção no dia a dia diminui. Pode parecer um ganho pequeno isoladamente, mas esse tipo de melhoria incremental no tooling impacta diretamente a produtividade ao longo do tempo.
O Husky continua sendo uma ferramenta sólida e amplamente utilizada no ecossistema JavaScript. Mas para cenários onde performance, paralelismo e organização da configuração são prioridades, o Lefthook se mostrou uma alternativa bastante interessante.