ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 36

  1. Blog

lefthook vs husky: Should You Switch? 615ms vs 478ms

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.

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. Is lefthook faster than husky on a prettier pre-commit?
  3. How long does hook install take?
  4. Should you switch from husky to lefthook?
  5. Sources
  6. Related

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.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM Linux cloud box, tested 5 Oct 2026 (about 23:20 to 23:25 IST). Shared box; variants interleaved each round.
  • Fixture: two git repos with the same 40 unformatted .js modules staged for commit. Task: run prettier 3.6.2 --write on those staged files.
  • Tools: husky 9.1.7 with lint-staged 16.2.3; lefthook 1.13.6. Node at the time of the hook runs was v22.14.0 via the Volta default on the box.
  • Timing: one warmup each, then five interleaved rounds. Wall clock via process.hrtime around the hook command (not a full git commit, so empty-commit noise is out of the number).
  • Findings: local-bin medians 477.5 ms (husky/lint-staged) vs 614.5 ms (lefthook calling node_modules/.bin/prettier). Install medians 282.5 ms (husky) vs 255.9 ms (lefthook). Bare prettier without any hook framework: 464 ms.
  • One surprise: lefthook's Go binary did not win this single-command case. Most of the wall time is prettier plus process startup; an extra runner layer still shows up at this size.
  • Not tested: many parallel lefthook commands, monorepo per-package hooks, eslint on TypeScript, Windows/macOS, pre-push, commit-msg.

Is lefthook faster than husky on a prettier pre-commit?

VariantMedian wallRuns (ms)
husky path: local lint-staged --allow-empty478 ms478 / 459 / 474 / 478 / 488
lefthook path: local lefthook + local prettier615 ms614 / 617 / 615 / 621 / 610
husky path: npx lint-staged --allow-empty651 ms628 / 651 / 630 / 694 / 689
lefthook path: npx lefthook + npx prettier765 ms758 / 750 / 765 / 787 / 884
Bare npx prettier --write src/*.js (no hook)464 ms457 / 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.

How long does hook install take?

InstallMedian wallRuns (ms)
npx husky then write .husky/pre-commit283 ms277 / 283 / 344 / 348 / 265
npx lefthook install256 ms255 / 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.

Should you switch from husky to lefthook?

SituationMy pick
Single prettier or eslint pre-commit, already on lint-stagedStay on husky; it was faster here
You want YAML config and a Go runner checked into the repolefthook
Monorepo with many parallel hook commandslefthook (not measured; that is the product pitch)
Team is happy and hooks finish under a secondDo not switch this quarter
You are choosing a linter/formatter firstFix 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.

Sources

  • https://github.com/typicode/husky
  • https://github.com/lint-staged/lint-staged
  • https://github.com/evilmartians/lefthook
  • https://www.npmjs.com/package/husky
  • https://www.npmjs.com/package/lefthook
  • https://github.com/prettier/prettier

Related

  • https://www.shoppercove.com/blog/dprint-vs-prettier
  • https://www.shoppercove.com/blog/biome-vs-eslint-prettier
  • https://www.shoppercove.com/blog/oxlint-vs-eslint
  • https://www.shoppercove.com/blog/knip-vs-depcheck
  • https://www.shoppercove.com/blog/turbo-vs-nx
  • https://www.shoppercove.com/blog/madge-vs-dependency-cruiser
  • https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
  • https://www.shoppercove.com/blog/c8-vs-nyc
lefthookhuskylint-stagedgit hooksperformancebenchmarkprettierpre-commit

Lab evidence

What I found running this

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.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 88

    Sharp vs Jimp: 112ms vs 366ms Resize

    sharp 0.35.5 vs Jimp 1.6.1 on one 1920×1080 JPEG → width 800 JPEG q80. Warm medians (7 rounds after 1 warm-up): sharp 112 ms / 142,435 B vs Jimp 366 ms / 269,590 B (~3.3×). Fixture /workspace/bench-sharp-jimp/.

    5 Oct 2026

  • Plate 73

    volta vs fnm: Should You Switch? 14ms vs 17ms

    volta 2.0.2 vs fnm 1.39.0 switching Node 20.19.2 ↔ 22.14.0: session A-then-B median 13.9 ms vs 17.0 ms; steady node -v 7.4 ms vs 6.4 ms (direct 4.7 ms).

    5 Oct 2026

  • Plate 94

    Should You Leave Prettier? 1.59s vs 0.51s

    dprint 0.60.1 vs Prettier 3.9.9 on 180 files (120 JS + 40 JSON + 20 MD, 38925 B pristine): write medians 514 ms vs 1586 ms; check 455 ms vs 1313 ms. Output 44805 vs 45285 B. All 120 JS files differed on arrow-param parentheses under these defaults.

    5 Oct 2026

On this page

  1. What I tested
  2. Is lefthook faster than husky on a prettier pre-commit?
  3. How long does hook install take?
  4. Should you switch from husky to lefthook?
  5. Sources
  6. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove