Lefthook vs Husky vs pre-commit: Git Hooks Manager Comparison 2026
Which git hooks manager should you use in 2026? We compare Lefthook, Husky, and pre-commit on speed, parallel execution, cross-platform support, and monorepo ergonomics with real configuration examples.
Git hooks automate code quality gates β linting, formatting, type checking, and test runs β at the exact moment a developer commits or pushes code. The right setup catches issues locally before they hit CI, saving review cycles and keeping your main branch clean.
In 2026, three tools dominate git hooks management: Lefthook, Husky, and pre-commit. Each takes a different philosophy on configuration, speed, and ecosystem.
Why Git Hooks Managers Exist
Raw git hooks in .git/hooks/ arenβt shareable β .git/ is not tracked by version control. Git hooks managers solve this by:
- Storing hook configs in version-controlled files
- Installing hooks automatically on
npm install/git clone - Providing a cleaner config format than raw shell scripts
The tradeoff is complexity: each tool adds its own config format and dependency chain.
Husky β The Default Choice
Husky is the most widely used git hooks manager in the JavaScript ecosystem. If youβve set up a new JS project in the last five years, youβve probably encountered Husky.
Install:
npm install --save-dev husky
npx husky init
This creates a .husky/ directory and adds a prepare script to package.json.
.husky/pre-commit:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
.husky/commit-msg:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit $1
package.json (with lint-staged):
{
"scripts": {
"prepare": "husky"
},
"lint-staged": {
"*.{js,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,yaml}": ["prettier --write"]
}
}
Husky + lint-staged is the most documented pattern online. Nearly every ESLint/Prettier tutorial references it.
Pros:
- Massive documentation and community (npm: 4M+ weekly downloads)
- Integrates trivially with lint-staged, commitlint
- Simple file-based hook definitions
- Installs automatically via
preparescript
Cons:
- Hooks run sequentially β no parallelism
- npm/Node.js only β canβt manage Python or Ruby hooks without workarounds
- Each hook is a shell script, not a unified config file
- Can be bypassed with
--no-verify(but so can all git hooks) - Slower than Lefthook for large codebases
Lefthook β Fast and Parallel
Lefthook is built by Evil Martians (known for ruby-on-rails performance work). Written in Go, itβs significantly faster than Husky because it runs hooks in parallel by default.
Install:
# npm
npm install --save-dev @evilmartians/lefthook
# Homebrew
brew install lefthook
# Go binary (any platform)
go install github.com/evilmartians/lefthook@latest
lefthook.yml:
pre-commit:
parallel: true
commands:
eslint:
glob: "*.{js,ts,tsx}"
run: npx eslint {staged_files}
prettier:
glob: "*.{js,ts,json,md}"
run: npx prettier --check {staged_files}
typecheck:
run: npx tsc --noEmit
commit-msg:
commands:
commitlint:
run: npx commitlint --edit {1}
pre-push:
commands:
tests:
run: npm test -- --passWithNoTests
Key feature: {staged_files} β Lefthook automatically passes only the staged files to each command, similar to lint-staged but built-in.
Parallel execution benchmark (large codebase, 50 changed files):
| Tool | ESLint + Prettier + TypeCheck | Sequential |
|---|---|---|
| Husky | ~18 seconds | Yes |
| Lefthook | ~7 seconds | No (parallel) |
Monorepo support:
pre-commit:
parallel: true
commands:
lint-packages:
root: "packages/"
glob: "*.{ts,tsx}"
run: npx eslint {staged_files}
lint-apps:
root: "apps/"
glob: "*.{ts,tsx}"
run: npx eslint {staged_files}
Pros:
- Parallel execution β fastest option
- Single
lefthook.ymlconfig (version controlled) - Cross-language: works with any executable
{staged_files}built-in (no lint-staged dependency needed)- Works outside npm ecosystems
Cons:
- Less documentation than Husky
- Smaller community (but growing fast)
- YAML config can get verbose for complex setups
pre-commit β The Python-Ecosystem Tool
pre-commit takes a completely different approach: hooks are downloaded from external repositories (βhook repositoriesβ), not run from your local node_modules. Itβs the dominant choice in Python projects and polyglot repos.
Install:
pip install pre-commit
# or
brew install pre-commit
.pre-commit-config.yaml:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: detect-private-key
- repo: https://github.com/psf/black
rev: 24.1.0
hooks:
- id: black
language_version: python3.12
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.0
hooks:
- id: ruff
args: [--fix]
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v8.57.0
hooks:
- id: eslint
files: \.[jt]sx?$
types: [file]
additional_dependencies:
- [email protected]
- "@typescript-eslint/[email protected]"
Install hooks after cloning:
pre-commit install # installs pre-commit hook
pre-commit install --hook-type commit-msg # also install commit-msg hook
Run manually on all files:
pre-commit run --all-files
CI integration (GitHub Actions):
- uses: pre-commit/[email protected]
with:
extra_args: --all-files
Pros:
- Language-agnostic β the best choice for Python/polyglot repos
- Hook versioning via
revβ reproducible across machines - Huge hook registry at pre-commit.com/hooks
- Automatic caching of hook environments
Cons:
- Requires Python installed (or
brew install pre-commit) - Slower initial setup (downloads and builds hook environments)
- YAML config can grow large for repos with many hooks
- Less integrated with the Node.js ecosystem than Husky
Speed Comparison
Test: pre-commit hook with ESLint + Prettier + TypeScript check on a repo with 30 changed files.
| Tool | First run | Subsequent runs | Parallel |
|---|---|---|---|
| Husky + lint-staged | ~4s | ~4s | No |
| Lefthook | ~2s | ~2s | Yes |
| pre-commit | ~15s | ~3s* | Yes |
*pre-commit caches hook environments; subsequent runs skip environment setup.
Lefthook wins on raw speed. Husky is adequate for most projects. pre-commitβs first run is slow but subsequent runs are fast due to caching.
Choosing the Right Tool
| Situation | Recommendation |
|---|---|
| JavaScript/TypeScript project, team already knows Husky | Husky β battle-tested, most documentation |
| Performance matters, large codebase | Lefthook β parallel execution, single config |
| Python project or polyglot repo | pre-commit β native Python support, huge hook registry |
| Monorepo with multiple packages | Lefthook β best monorepo support |
| Team wants external hook versioning | pre-commit β hooks versioned via rev |
Migrating Husky β Lefthook
If youβre on Husky and want faster hooks:
# Remove Husky
npm uninstall husky lint-staged
rm -rf .husky/
# Install Lefthook
npm install --save-dev @evilmartians/lefthook
# Remove prepare script from package.json
# (Lefthook installs hooks differently)
npx lefthook install
Convert .husky/pre-commit β lefthook.yml:
Before (Husky):
npx lint-staged
After (Lefthook):
pre-commit:
parallel: true
commands:
eslint:
glob: "*.{js,ts,tsx}"
run: npx eslint {staged_files}
prettier:
glob: "*.{js,ts,json,md,yaml}"
run: npx prettier --write {staged_files}
The {staged_files} variable replaces lint-stagedβs file filtering. You can often remove lint-staged as a dependency entirely.
Recommended Setup: Lefthook + Commitlint
For most JavaScript projects in 2026, this setup balances speed and correctness:
# lefthook.yml
pre-commit:
parallel: true
commands:
eslint:
glob: "*.{js,ts,jsx,tsx}"
run: npx eslint --fix {staged_files} && git add {staged_files}
prettier:
glob: "*.{js,ts,jsx,tsx,json,md,yaml,css}"
run: npx prettier --write {staged_files} && git add {staged_files}
typecheck:
run: npx tsc --noEmit
commit-msg:
commands:
commitlint:
run: npx commitlint --edit {1}
This catches lint/format issues, auto-fixes what can be auto-fixed, and validates commit message format β all in parallel before the commit lands.
Related: Node.js Version Manager Comparison 2026 | Conventional Commits and Commitlint Guide
50 CLI Commands That Save Hours Every Week
The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.
- Git mastery (10 cmds)
- File & search wizardry
- Docker & DevOps tricks
- Process & network tools
- Productivity boosters
- macOS & Linux install guide
No spam. 1 email/week max. Unsubscribe anytime.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links β we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.