
Introduction
Every developer has committed code with missing semicolons, failed tests, or inconsistent formatting at least once. However, these small mistakes can add up quickly, affecting the overall quality of your codebase. That’s where Git hooks come in. They allow you to automate code quality checks before commits or pushes happen. In this post, you’ll learn what Git hooks are, how to use them, and how to set up pre-commit hooks for linting, testing, and formatting.
What Are Git Hooks?
Git hooks are scripts that run automatically in response to Git events. For example, you can run a script every time a commit is made, a branch is pushed, or a merge is attempted.
Common Hook Types
- pre-commit: Runs before you make a commit. Perfect for linting and formatting.
- pre-push: Executes before pushing to a remote repository. Useful for running tests or build steps.
- commit-msg: Validates commit messages to enforce standards.
By leveraging these hooks, you can catch problems early and enforce team-wide quality standards automatically.
Why Use Git Hooks for Code Quality?
Using Git hooks ensures consistency and prevents broken code from entering your repository. In addition, it reduces the manual effort needed to maintain standards.
Key Benefits
- Automated linting: Fix common syntax and style issues before commit.
- Automated testing: Prevents pushing untested or failing code.
- Commit validation: Enforces commit message conventions (like Conventional Commits).
- Team consistency: Everyone follows the same rules without manual checks.
As a result, Git hooks act as a local safety net before your CI/CD pipeline even runs.
Setting Up Pre-Commit Hooks
Let’s go step-by-step through an example using Node.js and Husky, one of the most popular tools for managing Git hooks.
1. Install Husky
npm install husky --save-dev
npx husky install
Then enable hooks in your project:
npm pkg set scripts.prepare="husky install"
npm run prepare
2. Add a Pre-Commit Hook
Create a hook that runs linting and tests before committing:
npx husky add .husky/pre-commit "npm run lint && npm test"
git add .husky/pre-commit
Now, whenever you commit, Husky automatically runs npm run lint and npm test.
3. Add Commit Message Validation
If you want consistent commit messages, add a commit-msg hook:
npx husky add .husky/commit-msg "npx commitlint --edit \$1"
Combine this with Commitlint to enforce rules like feat:, fix:, or chore: prefixes.
Without Husky: Manual Hook Example
You can also create hooks manually in the .git/hooks directory.
Example pre-commit script:
#!/bin/sh
npm run lint
npm test
Save it as .git/hooks/pre-commit and make it executable:
chmod +x .git/hooks/pre-commit
While this works fine for small projects, tools like Husky make sharing and version-controlling hooks much easier.
Popular Tools for Managing Git Hooks
- Husky: The go-to tool for JavaScript and TypeScript projects.
- pre-commit: A Python-based framework supporting multiple languages.
- lefthook: A fast, cross-language Git hook manager for teams.
- lint-staged: Runs linters only on changed files for faster performance.
These tools integrate easily with CI/CD and work across operating systems.
Best Practices
- Keep hooks fast to avoid slowing down developers.
- Run heavy tests on pre-push instead of pre-commit.
- Use lint-staged to limit checks to changed files.
- Store hook configurations in your repository for team-wide consistency.
- Combine hooks with CI pipelines for full automation.
By following these practices, you ensure hooks enhance productivity rather than hinder it.
Real-World Example
Here’s a complete setup example combining multiple tools:
npm install husky lint-staged eslint --save-dev
Then add to your package.json:
{
"lint-staged": {
"*.js": ["eslint --fix", "git add"]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"pre-push": "npm test"
}
}
}
This setup automatically lints changed files and runs tests before pushing code, guaranteeing higher quality at every step.
Final Thoughts
Git hooks are one of the simplest yet most effective ways to automate quality checks and enforce coding standards. They act as your first line of defense, catching issues before CI/CD runs. Whether you’re using Husky, pre-commit, or custom scripts, adding Git hooks to your workflow ensures cleaner commits and fewer regressions. To take automation further, check out Securing CI/CD Pipelines: Supply-Chain Best Practices for protecting your pipelines end-to-end. For official reference, visit the Git Hooks documentation.



