
Git hooks help teams enforce code quality by automating checks at key stages like commits and pushes. Lefthook is a modern Git hook manager built for speed and collaboration. In this guide, you’ll learn how to use Lefthook with npm to streamline your Git workflow.
Lefthook is a fast Git hook manager that allows you to define and run custom scripts during Git events such as pre-commit, pre-push, and commit-msg. It improves workflow consistency by automating code formatting, linting, and testing.
Unlike legacy hook tools that write scripts per hook, Lefthook uses a central runner that simplifies setup and improves performance. It supports multiple programming environments including Node.js, Go, and Ruby.
Lefthook is widely used in teams to:
The central configuration and cross-platform compatibility make it a preferred choice for scalable engineering teams.
Git hooks are executable scripts placed in the .git/hooks directory. They are triggered by Git actions like committing or pushing code.
Each Git hook has a specific purpose:
pre-commit: Runs before a commit is createdcommit-msg: Runs after a commit message is writtenpre-push: Runs before pushing code to a remoteThese hooks can enforce standards, run tests, or prevent unsafe code from reaching the main branch. Without a hook manager, they must be created and maintained manually. Tools like Lefthook automate this process and enforce uniform behavior across developers.
The recommended package for Lefthook is lefthook, published and maintained by Evil Martians.
Install it as a dev dependency:
npm install --save-dev lefthook
After installation, set up the Git hook scripts by running:
npx lefthook install
This command links Lefthook to the .git/hooks folder and prepares your project to run the configured hooks. You should commit this setup to ensure that all team members share the same hook configuration.
For teams, it’s best to add this to your prepare script so hooks are installed automatically after running npm install:
"scripts": {
"prepare": "lefthook install"
}This ensures hooks are always set up, even on fresh clones or new environments.
Lefthook reads its configuration from a lefthook.yml file placed in the project root. This file defines what commands run during Git events and how.
A basic example to lint and format code before a commit:
pre-commit:
parallel: true
commands:
eslint:
run: npm run lint
prettier:
run: npm run formatYou can run commands on only staged files using {staged_files}:
pre-commit:
commands:
lint-js:
run: npx eslint {staged_files}
files: "*.js"Lefthook supports:
This config file should be committed to version control so everyone on the team uses the same hook logic.
npm and Lefthook work well together because Lefthook can run any command, including npm scripts. It’s a good practice to define hook logic in package.json and call it from lefthook.yml.
Example package.json:
"scripts": {
"lint": "eslint .",
"format": "prettier --write .",
"test": "jest"
}In lefthook.yml, you can then run these scripts:
pre-commit:
commands:
lint:
run: npm run lint
format:
run: npm run format
pre-push:
commands:
test:
run: npm run testThis separation keeps your YAML config clean and makes it easier to reuse commands across hooks or CI steps.
For CI environments, Git hooks don’t trigger automatically. Instead, use:
npx lefthook run pre-commit
This ensures the same checks run during pull requests or automated pipelines.
Lefthook is typically used for:
commit-msg hooks.Example to check commit messages:
commit-msg:
scripts:
validate:
run: commitlint -E HUSKY_GIT_PARAMSIn monorepos, you can scope hooks to specific packages or apps. For example, lint only changed files in a particular folder:
pre-commit:
commands:
lint-app:
run: npm run lint
include: "apps/app-a/**/*"This makes Lefthook suitable for large codebases with multiple subprojects or technologies.
If Lefthook doesn’t work, check these:
npx lefthook install again and check .git/hooks contains Lefthook scripts.npx lefthook run pre-commitchmod +x .git/hooks/*DEBUG=lefthook for verbose output to trace execution problems.You can also add fail_text in your config for custom error messages:
pre-commit:
commands:
lint:
run: npm run lint
fail_text: "Linting failed. Please fix before committing."This improves clarity for teammates and reduces friction during development.
lefthook.yml file so all developers share the same logic.npm install via the prepare script.{staged_files} to limit tools to changed files only.Teams benefit most when Lefthook acts as a shared enforcement tool. It replaces tribal knowledge with automation.
| Feature | Lefthook | Husky |
|---|---|---|
| Language Support | Node.js, Ruby, Go | Node.js only |
| Speed | Fast, parallel execution | Slower, sequential by default |
| Monorepo Support | Native with includes | Requires extra config |
| CI Compatibility | Manual run supported | Manual run supported |
| Setup Simplicity | Central config | Multiple scripts |
Lefthook is better suited for polyglot and large-scale projects. It also outperforms Husky in execution time and configuration clarity.
Is Lefthook compatible with Windows?
Yes. Lefthook works across all major platforms, including Windows, macOS, and Linux. It’s built to be cross-platform out of the box, so no additional setup is required for Windows environments.
Can you use Lefthook without Node.js?
Yes. Although Lefthook is commonly used with npm in JavaScript projects, it also supports Go and Ruby environments. You’re not locked into Node.js, making Lefthook suitable for polyglot or backend-heavy stacks.
Does Lefthook support monorepos?
Yes. Lefthook is built with monorepos in mind. You can scope hook logic using include and exclude patterns in the config file. This allows you to run specific checks on individual apps or packages inside a larger codebase.
How do you run Lefthook in CI environments?
Git hooks don’t trigger automatically in CI pipelines, but you can run Lefthook manually using npx lefthook run <hook>. This ensures that the same validation steps run in both developer machines and CI builds.
Is Lefthook faster than Husky?
Yes. Lefthook is optimized for performance. It executes commands in parallel by default and avoids redundant work by limiting scope to staged files. Teams migrating from Husky often report noticeable speed improvements in large projects.
Use Lefthook by installing the lefthook npm package, linking it to your Git hooks with npx lefthook install, and defining hook logic in lefthook.yml. Combine it with npm scripts for clean integration. Use it in CI with npx lefthook run. Version your config, use {staged_files} for efficiency, and automate installation with a prepare script.
Lefthook gives you full control over Git workflows, with better performance and fewer edge cases than other tools.
Google Chrome has dominated web browsing for over a decade with 71.77% global market share.…
Perplexity just made its AI-powered browser, Comet, completely free for everyone on October 2, 2025.…
You've probably heard about ChatGPT Atlas, OpenAI's new AI-powered browser that launched on October 21,…
Perplexity Comet became free for everyone on October 2, 2025, bringing research-focused AI browsing to…
ChatGPT Atlas launched on October 21, 2025, but it's only available on macOS. If you're…
Two AI browsers just entered the ring in October 2025, and they're both fighting for…