Fast and powerful Git hooks manager for any type of projects.
8,799
stars
977
commits
Go
primary language
Sep 7, 2026
updated
A Git hooks manager for Node.js, Ruby, Python and many other types of projects.
Lefthook is built by Evil Martians, an American design and engineering consultancy for developer tools, AI, and cybersecurity startups.
With Go (>= 1.26):
go install github.com/evilmartians/lefthook/v2@v2.1.11
go get -tool github.com/evilmartians/lefthook/v2@v2.1.11
With NPM:
npm install lefthook --save-dev
For Ruby:
gem install lefthook
For Python:
pipx install lefthook
Installation guide with more ways to install lefthook: apt, brew, winget, and others.
Configure your hooks, install them once and forget about it: rely on the magic underneath.
# Configure your hooks
vim lefthook.yml
# Install them to the git project
lefthook install
# Enjoy your work with git
git add -A && git commit -m '...'
lefthook.yml config options.Gives you more speed. docs
pre-push:
parallel: true
If you want your own list. Custom and prebuilt examples.
pre-commit:
jobs:
- name: lint frontend
run: yarn eslint {staged_files}
- name: lint backend
run: bundle exec rubocop --force-exclusion -- {all_files}
- name: stylelint frontend
files: git diff --name-only HEAD @{push}
run: yarn stylelint {files}
If you want to filter list of files. You could find more glob pattern examples here.
pre-commit:
jobs:
- name: lint backend
glob: "*.rb" # glob filter
exclude:
- "*/application.rb"
- "*/routes.rb"
run: bundle exec rubocop --force-exclusion -- {all_files}
If you want to execute the commands in a relative path
pre-commit:
jobs:
- name: lint backend
root: "api/" # Careful to have only trailing slash
glob: "*.rb" # glob filter
run: bundle exec rubocop -- {all_files}
If oneline commands are not enough, you can execute files. docs
commit-msg:
jobs:
- script: "template_checker"
runner: bash
If you want to control a group of commands. docs
pre-push:
jobs:
- name: audit packages
tags:
- frontend
- linters
run: yarn lint
- name: audit gems
tags:
- backend
- security
run: bundle audit
If you are in the Docker environment. docs
pre-commit:
jobs:
- script: "good_job.js"
runner: docker run -it --rm <container_id_or_name> {cmd}
If you are a frontend/backend developer and want to skip unnecessary commands or override something in Docker. docs
# lefthook-local.yml
pre-push:
exclude_tags:
- frontend
jobs:
- name: audit packages
skip: true
If you want to run hooks group directly.
$ lefthook run pre-commit
If you want to run specific group of commands directly.
fixer:
jobs:
- run: bundle exec rubocop --force-exclusion --safe-auto-correct -- {staged_files}
- run: yarn eslint --fix {staged_files}
$ lefthook run fixer
You can control what lefthook prints with output option.
output:
- execution
- failure
Check examples
(top 30 of 136)
Go
87.2%
JavaScript
4.9%
Raku
4.1%
Shell
1.3%
Python
1.3%
Fast and powerful Git hooks manager for any type of projects.
8,799
stars
977
commits
Go
primary language
Sep 7, 2026
updated
A Git hooks manager for Node.js, Ruby, Python and many other types of projects.
Lefthook is built by Evil Martians, an American design and engineering consultancy for developer tools, AI, and cybersecurity startups.
With Go (>= 1.26):
go install github.com/evilmartians/lefthook/v2@v2.1.11
go get -tool github.com/evilmartians/lefthook/v2@v2.1.11
With NPM:
npm install lefthook --save-dev
For Ruby:
gem install lefthook
For Python:
pipx install lefthook
Installation guide with more ways to install lefthook: apt, brew, winget, and others.
Configure your hooks, install them once and forget about it: rely on the magic underneath.
# Configure your hooks
vim lefthook.yml
# Install them to the git project
lefthook install
# Enjoy your work with git
git add -A && git commit -m '...'
lefthook.yml config options.Gives you more speed. docs
pre-push:
parallel: true
If you want your own list. Custom and prebuilt examples.
pre-commit:
jobs:
- name: lint frontend
run: yarn eslint {staged_files}
- name: lint backend
run: bundle exec rubocop --force-exclusion -- {all_files}
- name: stylelint frontend
files: git diff --name-only HEAD @{push}
run: yarn stylelint {files}
If you want to filter list of files. You could find more glob pattern examples here.
pre-commit:
jobs:
- name: lint backend
glob: "*.rb" # glob filter
exclude:
- "*/application.rb"
- "*/routes.rb"
run: bundle exec rubocop --force-exclusion -- {all_files}
If you want to execute the commands in a relative path
pre-commit:
jobs:
- name: lint backend
root: "api/" # Careful to have only trailing slash
glob: "*.rb" # glob filter
run: bundle exec rubocop -- {all_files}
If oneline commands are not enough, you can execute files. docs
commit-msg:
jobs:
- script: "template_checker"
runner: bash
If you want to control a group of commands. docs
pre-push:
jobs:
- name: audit packages
tags:
- frontend
- linters
run: yarn lint
- name: audit gems
tags:
- backend
- security
run: bundle audit
If you are in the Docker environment. docs
pre-commit:
jobs:
- script: "good_job.js"
runner: docker run -it --rm <container_id_or_name> {cmd}
If you are a frontend/backend developer and want to skip unnecessary commands or override something in Docker. docs
# lefthook-local.yml
pre-push:
exclude_tags:
- frontend
jobs:
- name: audit packages
skip: true
If you want to run hooks group directly.
$ lefthook run pre-commit
If you want to run specific group of commands directly.
fixer:
jobs:
- run: bundle exec rubocop --force-exclusion --safe-auto-correct -- {staged_files}
- run: yarn eslint --fix {staged_files}
$ lefthook run fixer
You can control what lefthook prints with output option.
output:
- execution
- failure
Check examples
(top 30 of 136)
Go
87.2%
JavaScript
4.9%
Raku
4.1%
Shell
1.3%
Python
1.3%