Modern native Git hooks
Husky is a lightweight npm package that manages Git hooks directly within your JavaScript project repository. Instead of manually editing scripts in the .git/hooks directory (which aren't version-controlled), Husky creates shareable hook files in a .husky/ directory that travels with your codebase. When developers clone your repository and run npm install, hooks automatically configure themselves via the prepare script.
The package leverages Git's native core.hooksPath feature to redirect hook execution to your project directory, making it both fast (executes in ~1ms) and dependency-free at just 2 kB. This architecture supports all 13 Git client-side hooks including pre-commit, pre-push, commit-msg, and post-merge. Husky works across macOS, Linux, and Windows environments, with full support for Git GUIs, monorepos, and projects using nvm or other Node version managers.
With over 20 million weekly downloads, Husky is used in high-profile projects like Next.js, webpack, and Angular. It excels at enforcing code quality gates by running ESLint, Prettier, Jest, or custom scripts before commits reach the repository. The tool integrates seamlessly with lint-staged for optimized pre-commit workflows that only process staged files, making it a standard component in modern JavaScript CI/CD pipelines.
Husky v9 emphasizes zero-configuration simplicity while maintaining advanced features like branch-specific logic, POSIX shell scripting, and opt-out mechanisms via --no-verify. The package automatically cleans up hooks on uninstall and requires no background processes or daemons, making it a transparent addition to existing development workflows.
// 1. Install and initialize Husky
// npm install husky --save-dev
// npx husky init
// 2. package.json configuration
{
"scripts": {
"prepare": "husky",
"lint": "eslint . --fix",
"format": "prettier --write .",
"test": "jest"
},
"devDependencies": {
"husky": "^9.1.7",
"lint-staged": "^15.0.0"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,css}": ["prettier --write"]
}
}
// 3. Create .husky/pre-commit hook
// File: .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
npm run test -- --bail --findRelatedTests
// 4. Create .husky/commit-msg hook for commit validation
// File: .husky/commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
commit_msg=$(cat "$1")
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|chore|refactor|test):"; then
echo "Error: Commit message must start with feat:|fix:|docs:|chore:|refactor:|test:"
exit 1
fi
// 5. Create .husky/pre-push hook
// File: .husky/pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch" = "main" ]; then
npm run test -- --coverage --coverageThreshold='{"global":{"lines":80}}'
else
npm run test
fiAutomated code quality enforcement: Run ESLint and Prettier on every commit to prevent broken or poorly formatted code from entering version control. Teams use pre-commit hooks to execute npm run lint and npm run format, catching style violations before code review begins.
Test execution gating: Configure pre-push hooks to run your test suite with npm test before allowing pushes to remote branches. This prevents CI pipeline failures by ensuring all tests pass locally first, saving time and compute resources on continuous integration servers.
Commit message validation: Use commit-msg hooks with tools like commitlint to enforce conventional commit standards (e.g., feat:, fix:, chore:). This maintains clean Git history for automated changelog generation and semantic versioning workflows.
Staged file optimization: Combine Husky with lint-staged to run linters only on files being committed rather than the entire codebase. A pre-commit hook executes npx lint-staged, which applies ESLint and Prettier exclusively to modified files, dramatically reducing hook execution time in large projects.
Security scanning and dependency checks: Implement pre-commit hooks that run npm audit or scan for leaked secrets using tools like git-secrets. This catches vulnerable dependencies or accidentally committed API keys before they reach shared branches or production environments.
npm install huskypnpm add huskybun add husky