Lesson Completion
Back to course

Hook Best Practices

Beginner
7 minutes4.7Git

The Hook (The "Byte-Sized" Intro)

A good hook takes 2 seconds and catches real issues. A bad hook takes 30 seconds, fails randomly, and makes developers hate hooks. The difference? Speed, clarity, and reliability. If your hook is slow, flaky, or gives cryptic errors, developers will --no-verify every commit — defeating the entire purpose.

📖 What are Hook Best Practices?

Guidelines for creating hooks that are fast, reliable, and helpful — encouraging adoption instead of avoidance.

Conceptual Clarity

The 7 hook rules:

#RuleWhy
1Keep hooks fastSlow hooks get bypassed
2Only check staged filesDon't check unrelated files
3Give clear error messagesDevelopers need to know what failed
4Avoid flaky checksRandom failures erode trust
5Allow escape hatchDocument --no-verify for emergencies
6Match CI checksHooks should catch same issues as CI
7Version hooksStore in repo, review in PRs

Speed targets:

HookTarget TimeIf Slower
pre-commit< 5 secondsOnly lint staged files
commit-msg< 1 secondRegex only, no network
pre-push< 30 secondsAcceptable for full tests

Real-Life Analogy

Good hooks are like a quick security scan at the door — a 3-second bag check. Bad hooks are like a full-body MRI before entering every room. People stop going through the door.

Visual Architecture

flowchart TD FAST["⚡ Fast"] --> GOOD["✅ Good Hook"] CLEAR["💬 Clear Errors"] --> GOOD RELIABLE["🎯 Reliable"] --> GOOD STAGED["📄 Staged Files Only"] --> GOOD style GOOD fill:#1b2d1b,stroke:#53d8fb,color:#53d8fb

Why It Matters

  • Adoption: Fast, reliable hooks get used. Slow, flaky hooks get bypassed.
  • Trust: Consistent behavior builds developer confidence.
  • Efficiency: Hooks should complement CI, not duplicate it.
  • Culture: Good hooks create a culture of quality.

Code

bash
# ─── Good: fast, staged-only, clear messages ─── cat > .git/hooks/pre-commit << 'EOF' #!/bin/sh # Only lint staged files (fast!) FILES=$(git diff --cached --name-only --diff-filter=ACMR -- '*.js' '*.ts') if [ -z "$FILES" ]; then exit 0 # No staged JS/TS files, skip fi echo "$FILES" | xargs npx eslint if [ $? -ne 0 ]; then echo "" echo "❌ ESLint found issues in staged files." echo " Fix them or use 'git commit --no-verify' to skip." exit 1 fi echo "✅ Lint passed." EOF # ─── Bad: slow, checks everything, cryptic error ─── # DON'T DO THIS: # npm run lint ← Lints ALL files, not just staged # npm test ← Runs entire test suite on commit (too slow) # exit 1 ← No error message explaining what failed

Key Takeaways

  • Fast: Pre-commit < 5 seconds. Only check staged files.
  • Clear: Always explain what failed and how to fix it.
  • Reliable: No flaky checks that fail randomly.
  • Escapable: Document --no-verify for legitimate emergencies.

Interview Prep

  • Q: What makes a Git hook "good"? A: Speed (pre-commit < 5 seconds), reliability (no random failures), clarity (descriptive error messages), and scope (only checking staged files, not the entire project).

  • Q: Why should hooks only check staged files? A: Checking all files is slow and may flag issues in files you haven't changed. git diff --cached --name-only gives you only the staged files, keeping the hook fast and relevant.

  • Q: Should hooks be the same as CI checks? A: Hooks should catch the same types of issues (lint, format, tests) but at a lighter level — lint only staged files, not everything. CI is the definitive check; hooks are the fast first pass.

Topics Covered

Git HooksBest Practices

Tags

#git#hooks#best-practices#workflow

Last Updated

2026-02-13