# Claude Code Hooks — Automate Pre/Post Task Actions > Complete guide to Claude Code hooks for automating actions before and after tool calls. Set up linting, testing, notifications, and custom validation with shell commands. ## Install Save the content below to `.claude/skills/` or append to your `CLAUDE.md`: ## Quick Use ```json // ~/.claude/settings.json { "hooks": { "PreToolUse": [ { "matcher": "Write", "hooks": ["eslint --fix $CLAUDE_FILE_PATH"] } ], "PostToolUse": [ { "matcher": "Write", "hooks": ["npm test -- --related $CLAUDE_FILE_PATH"] } ] } } ``` ## What are Claude Code Hooks? Hooks are shell commands that Claude Code executes automatically before or after specific tool calls. They let you enforce coding standards, run tests, send notifications, or perform custom validation — without relying on Claude to remember. Hooks are harness-level automation: they run regardless of what Claude decides. **Answer-Ready**: Claude Code Hooks automate shell commands before/after tool calls. Run linting on file writes, tests after changes, notifications on commits. Configured in settings.json. Harness-level enforcement — runs regardless of Claude's decisions. Essential for team standardization. **Best for**: Teams wanting automated quality enforcement in Claude Code. **Works with**: Claude Code (all versions). **Setup time**: Under 5 minutes. ## Hook Events | Event | When It Fires | Use Case | |-------|--------------|----------| | PreToolUse | Before a tool runs | Validate, lint, backup | | PostToolUse | After a tool runs | Test, notify, format | | Notification | On status changes | Alerts, logging | | Stop | When Claude stops | Summary, cleanup | ## Matchers Matchers filter which tool triggers the hook: ```json { "hooks": { "PreToolUse": [ {"matcher": "Write", "hooks": ["..."]}, {"matcher": "Edit", "hooks": ["..."]}, {"matcher": "Bash", "hooks": ["..."]} ] } } ``` | Matcher | Triggers On | |---------|------------| | `Write` | File creation | | `Edit` | File modification | | `Bash` | Shell commands | | `Read` | File reads | | `*` | All tools | ## Practical Examples ### 1. Auto-Lint on Write ```json { "matcher": "Write", "hooks": ["npx prettier --write $CLAUDE_FILE_PATH"] } ``` ### 2. Run Related Tests ```json { "matcher": "Edit", "hooks": ["npm test -- --related $CLAUDE_FILE_PATH 2>&1 | tail -20"] } ``` ### 3. Prevent Writes to Protected Files ```json { "matcher": "Write", "hooks": ["if echo $CLAUDE_FILE_PATH | grep -q '/vendor/'; then echo 'BLOCKED: Cannot write to vendor/' >&2; exit 1; fi"] } ``` ### 4. TypeScript Type Check ```json { "matcher": "Write", "hooks": ["if echo $CLAUDE_FILE_PATH | grep -qE '\\.tsx?$'; then npx tsc --noEmit 2>&1 | head -20; fi"] } ``` ### 5. Git Stage After Write ```json { "matcher": "Write", "hooks": ["git add $CLAUDE_FILE_PATH"] } ``` ### 6. Notification on Completion ```json { "hooks": { "Stop": [ {"hooks": ["osascript -e 'display notification \"Claude Code finished\" with title \"Done\"'"]} ] } } ``` ## Environment Variables | Variable | Value | |----------|-------| | `$CLAUDE_FILE_PATH` | Path of the file being written/edited | | `$CLAUDE_TOOL_NAME` | Name of the tool being called | ## Hook Behavior - **Exit 0**: Hook passed, tool proceeds - **Exit non-zero**: Hook failed, tool is blocked (PreToolUse) or warning shown (PostToolUse) - **Stdout**: Shown to Claude as feedback - **Stderr**: Shown as warning/error - **Timeout**: Hooks timeout after 30 seconds by default ## Best Practices 1. **Keep hooks fast** — They run on every tool call. Slow hooks kill productivity 2. **Use PreToolUse for blocking** — Prevent bad writes before they happen 3. **Use PostToolUse for validation** — Run tests after changes 4. **Filter with matchers** — Don't run expensive hooks on Read operations 5. **Pipe output** — Use `| head -20` to limit verbose output 6. **Test locally first** — Run your hook command manually before configuring ## Hooks vs CLAUDE.md | Aspect | Hooks | CLAUDE.md | |--------|-------|-----------| | Type | Shell commands | Text instructions | | Enforcement | Automatic (harness) | Advisory (Claude reads) | | Reliability | 100% — always runs | Best effort | | Use case | Linting, testing, blocking | Conventions, guidance | ## FAQ **Q: Can hooks modify Claude's behavior?** A: Hooks provide feedback via stdout/stderr. Claude sees this feedback and can adjust. PreToolUse hooks can block operations by exiting non-zero. **Q: Do hooks slow down Claude?** A: Yes, hooks add latency. Keep them under 5 seconds. Use matchers to limit which tools trigger them. **Q: Can I use hooks for CI/CD-like workflows?** A: Yes, PostToolUse hooks can run test suites, type checking, and linting after every change — like a local CI pipeline. ## Source & Thanks > - [Claude Code Hooks Documentation](https://docs.anthropic.com/en/docs/claude-code/hooks) > - Configured in `~/.claude/settings.json` ## Quick Use Configure hooks in `~/.claude/settings.json` to auto-run shell commands before and after tool calls. ## What Are Claude Code Hooks? Hooks are shell commands Claude Code runs automatically before or after tool calls. Automate linting, testing, notifications, and validation — not reliant on Claude remembering. **TL;DR**: Claude Code automation hooks. Run shell commands before/after tool calls (lint/tests/block/notify). Configured in settings.json. Enforced at the harness level. ## Event Types PreToolUse (before tool), PostToolUse (after tool), Notification (status change), Stop (on completion). ## Practical Examples 1. Auto-format on write 2. Run related tests after edits 3. Block writes to protected files 4. TypeScript type-check 5. Desktop notification on completion ## Hooks vs CLAUDE.md Hooks = shell commands, 100% executed; CLAUDE.md = text instructions, best-effort compliance. ## Source & Thanks > [Claude Code Hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) --- Source: https://tokrepo.com/en/workflows/claude-code-hooks-automate-pre-post-task-actions-ba645a85 Author: Skill Factory