Skip to main content

Command Palette

Search for a command to run...

Husky Git Hooks: Modern Git Hook Manager

Updated
4 min readView as Markdown
T

Welcome to TopperBlog! 👋

I'm a tech content creator passionate about helping developers level up their careers and master cutting-edge technologies.

🎯 What I Write About: • AI/ML Engineering & LLMs • Web3 & Blockchain Development
• System Design & Architecture • Interview Preparation (FAANG) • Freelancing & Remote Work • Modern Tech Stacks (Next.js, React, Rust, TypeScript) • Performance Optimization & Best Practices

💼 Mission: Sharing practical, actionable insights that accelerate your tech career and maximize your earning potential.

📚 15+ In-Depth Guides covering everything from earning $10k/month as a freelancer to cracking FAANG interviews.

🌐 Let's connect and grow together in this amazing tech journey!

#TechBlogger #SoftwareEngineering #CareerGrowth #WebDevelopment #AIEngineering

Husky Git Hooks: Modern Git Hook Manager

Table of Contents

What is Husky?

Husky is a modern Git hooks manager that makes it easy to enforce quality standards in your projects. It allows you to run scripts automatically at various stages of the Git workflow (commit, push, etc.), ensuring code quality, running tests, and maintaining consistency across your team.

Key Benefits:

  • 🔒 Prevent bad commits and pushes
  • 🎯 Enforce code quality standards
  • 🚀 Automate linting, testing, and formatting
  • 👥 Share Git hooks with your team via package.json
  • ⚡ Zero dependencies and fast execution

Setup & Installation

Prerequisites

  • Node.js (v14 or higher)
  • npm or yarn
  • Git repository initialized

Installation Steps

# Install Husky
npm install --save-dev husky

# Initialize Husky
npx husky init

# This creates .husky/ directory and adds prepare script to package.json

Basic Configuration

After initialization, your package.json will include:

{
  "scripts": {
    "prepare": "husky"
  }
}

Code Examples

Example 1: Pre-commit Hook (Linting)

# Create pre-commit hook
npx husky add .husky/pre-commit "npm run lint"

# .husky/pre-commit file content:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint

Example 2: Pre-commit with Multiple Commands

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint
npm run format
npm run type-check

Example 3: Commit Message Validation (commitlint)

# Install commitlint
npm install --save-dev @commitlint/cli @commitlint/config-conventional

# Create commit-msg hook
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'

# commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'chore', 'refactor']]
  }
}

Example 4: Pre-push Hook (Run Tests)

# Create pre-push hook
npx husky add .husky/pre-push "npm test"

# .husky/pre-push
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
npm run build

Example 5: Staged Files Only (with lint-staged)

# Install lint-staged
npm install --save-dev lint-staged

# package.json configuration
{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{json,md,yml}": ["prettier --write"]
  }
}

# .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

Comparison Table

FeatureHusky v9Husky v4Native Git Hookspre-commit (Python)
Installationnpm packagenpm packageManual setuppip package
Team Sharing✅ Via package.json✅ Via package.json❌ Manual distribution✅ Via .pre-commit-config.yaml
Zero Dependencies✅ Yes❌ No✅ Yes❌ Requires Python
Cross-platform✅ Yes✅ Yes⚠️ Limited✅ Yes
ConfigurationSimple scriptsJSON configShell scriptsYAML config
Performance⚡ Fast⚡ Fast⚡ Fastest⚠️ Slower (Python)
TypeScript Support✅ Yes✅ Yes⚠️ Manual⚠️ Limited
Auto-install✅ prepare script✅ postinstall❌ No⚠️ Manual
Skip Hooks--no-verify--no-verify--no-verifySKIP=hook
Community Size🔥 Large🔥 Large📦 Built-in📦 Medium

FAQ

Q: How do I skip hooks temporarily?

A: Use the --no-verify or -n flag:

git commit -m "message" --no-verify
git push --no-verify

Q: Why aren't my hooks running?

A: Common issues:

  • Ensure prepare script runs: npm run prepare
  • Check hook file permissions: chmod +x .husky/pre-commit
  • Verify .husky directory exists
  • Check if hooks are executable

Q: Can I use Husky in a monorepo?

A: Yes! Install Husky at the root level:

# Root package.json
{
  "scripts": {
    "prepare": "husky"
  }
}

Q: How do I migrate from Husky v4 to v9?

A:

# Uninstall old version
npm uninstall husky

# Install new version
npm install --save-dev husky
npx husky init

# Recreate your hooks manually in .husky/ directory

Q: What's the difference between Husky and lint-staged?

A:

  • Husky: Manages Git hooks (when to run scripts)
  • lint-staged: Runs commands on staged files only (what to run)
  • They work great together!

Q: Can I use Husky with other package managers (yarn, pnpm)?

A: Yes!

# Yarn
yarn add --dev husky
yarn husky init

# pnpm
pnpm add --save-dev husky
pnpm exec husky init

Q: How do I disable Husky in CI/CD?

A: Set the HUSKY environment variable:

HUSKY=0 npm install  # Skips Husky installation

Q: Can I run different hooks for different branches?

A: Yes, add branch checking logic:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

branch=$(git rev-parse --abbrev-ref HEAD)

if [ "$branch" = "main" ]; then
  npm run full-test
else
  npm run quick-test
fi

End of Guide | For more information, visit typicode.github.io/husky