# Husky Git Hooks: Modern Git Hook Manager

# Husky Git Hooks: Modern Git Hook Manager

## Table of Contents
- [What is Husky?](#what-is-husky)
- [Setup & Installation](#setup--installation)
- [Code Examples](#code-examples)
- [Comparison Table](#comparison-table)
- [FAQ](#faq)

## 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

```bash
# 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:

```json
{
  "scripts": {
    "prepare": "husky"
  }
}
```

## Code Examples

### Example 1: Pre-commit Hook (Linting)

```bash
# 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

```bash
# .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)

```bash
# 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)

```bash
# 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)

```bash
# 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

| Feature | Husky v9 | Husky v4 | Native Git Hooks | pre-commit (Python) |
|---------|----------|----------|------------------|---------------------|
| **Installation** | npm package | npm package | Manual setup | pip 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 |
| **Configuration** | Simple scripts | JSON config | Shell scripts | YAML 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-verify` | `SKIP=hook` |
| **Community Size** | 🔥 Large | 🔥 Large | 📦 Built-in | 📦 Medium |

## FAQ

### Q: How do I skip hooks temporarily?
**A:** Use the `--no-verify` or `-n` flag:
```bash
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:
```bash
# Root package.json
{
  "scripts": {
    "prepare": "husky"
  }
}
```

### Q: How do I migrate from Husky v4 to v9?
**A:** 
```bash
# 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!
```bash
# 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:
```bash
HUSKY=0 npm install  # Skips Husky installation
```

### Q: Can I run different hooks for different branches?
**A:** Yes, add branch checking logic:
```bash
#!/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](https://typicode.github.io/husky)
