husky 9.1.7 + lint-staged 16.2.3 vs lefthook 1.13.6 on a 40-file prettier pre-commit: local-bin medians 478 ms vs 615 ms (~1.29x); npx path 651 ms vs 765 ms; install 283 ms vs 256 ms.
5 min read
On a 40-file prettier pre-commit, husky 9.1.7 plus lint-staged 16.2.3 took a median 478 ms when both used local binaries, and lefthook 1.13.6 took 615 ms (~1.29x). Hook install was close: lefthook 256 ms vs husky 283 ms. With the common npx wrappers the gap stayed in husky's favor (651 ms vs 765 ms).
Short answer: do not switch to lefthook for raw speed on a single prettier hook. Stay on husky plus lint-staged if that stack already works. Move to lefthook when you want a YAML-native Go runner, monorepo-friendly parallel commands, or to drop the lint-staged Node layer. No affiliate links in this post.
.js modules staged for commit. Task: run prettier 3.6.2 --write on those staged files.process.hrtime around the hook command (not a full git commit, so empty-commit noise is out of the number).node_modules/.bin/prettier). Install medians 282.5 ms (husky) vs 255.9 ms (lefthook). Bare prettier without any hook framework: 464 ms.| Variant | Median wall | Runs (ms) |
|---|---|---|
husky path: local lint-staged --allow-empty | 478 ms | 478 / 459 / 474 / 478 / 488 |
lefthook path: local lefthook + local prettier | 615 ms | 614 / 617 / 615 / 621 / 610 |
husky path: npx lint-staged --allow-empty | 651 ms | 628 / 651 / 630 / 694 / 689 |
lefthook path: npx lefthook + npx prettier | 765 ms | 758 / 750 / 765 / 787 / 884 |
Bare npx prettier --write src/*.js (no hook) | 464 ms | 457 / 468 / 468 / 464 / 463 |
No. On this 40-file fixture husky plus lint-staged was faster in both the local-binary and npx setups. Lefthook still beats a cold full Node toolchain story when you configure many parallel commands in YAML; that is not what I measured here. If your pre-commit is mostly format-on-save style work, see the dprint vs Prettier post and the Biome vs ESLint/Prettier post for the formatter choice underneath the hook.
| Install | Median wall | Runs (ms) |
|---|---|---|
npx husky then write .husky/pre-commit | 283 ms | 277 / 283 / 344 / 348 / 265 |
npx lefthook install | 256 ms | 255 / 305 / 265 / 256 / 254 |
Almost a wash. Lefthook was about 27 ms faster to wire the git hook on this box. Neither install time should decide a migration.
| Situation | My pick |
|---|---|
| Single prettier or eslint pre-commit, already on lint-staged | Stay on husky; it was faster here |
| You want YAML config and a Go runner checked into the repo | lefthook |
| Monorepo with many parallel hook commands | lefthook (not measured; that is the product pitch) |
| Team is happy and hooks finish under a second | Do not switch this quarter |
| You are choosing a linter/formatter first | Fix that before the hook runner; see oxlint vs ESLint and knip vs depcheck |
Bottom line: husky plus lint-staged won the 40-file prettier hook (478 ms vs 615 ms local binaries; 651 ms vs 765 ms with npx). lefthook install was slightly quicker (256 ms vs 283 ms). Who should not switch yet: repos whose only pain is "prettier on staged files" and who already ship husky. Who should try lefthook: teams that outgrew a one-line lint-staged config and want parallel, YAML-defined hooks.
How this was made: I built two identical 40-file git fixtures, ran interleaved hook and install timings on the ShopperCove test box, and kept the JSON; the write-up was drafted with AI help and checked against that output.
Lab evidence
Hands-on on ShopperCove box 5 Oct 2026 ~23:20-23:25 IST (8 vCPU Intel Xeon / 15 GB shared Linux). Fixture: 40 unformatted .js modules staged in twin git repos. Versions: husky 9.1.7, lint-staged 16.2.3, lefthook 1.13.6, prettier 3.6.2; Node v22.14.0 during hook runs. 1 warmup + 5 interleaved rounds (hook) and 5 for install. Medians install: husky 282.5 ms (276.7/282.5/343.7/347.7/265.2); lefthook 255.9 ms (254.9/304.8/264.9/255.9/254). Hook local bins: husky lint-staged 477.5 ms (477.5/459.2/473.5/478.2/487.8); lefthook+local prettier 614.5 ms (614.4/617.1/614.5/621.1/609.9). Hook npx path: husky 650.8 ms; lefthook+npx prettier 764.6 ms; bare npx prettier 464.0 ms. Timed hook command only (not full git commit). Raw: /workspace/bench-lefthook-husky/res-lefthook-husky.json. Not tested: parallel lefthook commands, monorepo hooks, eslint/TS, Windows/macOS, pre-push. No affiliate.