# 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 in your project root: ## 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` ## 快速使用 在 `~/.claude/settings.json` 中配置 hooks,自动在工具调用前后执行 shell 命令。 ## 什么是 Claude Code Hooks? Hooks 是 Claude Code 在工具调用前后自动执行的 shell 命令。自动化 lint、测试、通知和验证,不依赖 Claude 记忆。 **一句话总结**:Claude Code 自动化钩子,工具调用前后执行 shell 命令(lint/测试/阻止/通知),settings.json 配置,harness 级强制执行。 ## 事件类型 PreToolUse(工具前)、PostToolUse(工具后)、Notification(状态变化)、Stop(完成时)。 ## 实用示例 1. 写入时自动格式化 2. 修改后运行相关测试 3. 阻止写入受保护文件 4. TypeScript 类型检查 5. 完成时桌面通知 ## Hooks vs CLAUDE.md Hooks = shell 命令,100% 执行;CLAUDE.md = 文本指令,最大努力遵循。 ## 来源与致谢 > [Claude Code Hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) --- Source: https://tokrepo.com/en/workflows/ba645a85-3df0-40ab-8c75-15aec5c8a2af Author: Skill Factory