Hooks vs Commands
In Lesson 3 you learned about slash commands — workflows you trigger manually. Hooks are the opposite: they run automatically in response to events. You never invoke a hook. It fires on its own when its trigger condition is met.
This distinction matters. Commands are on-demand tools you reach for when you need them. Hooks are guardrails and automation that run whether you remember them or not. Together, they form a complete automation layer: commands handle the "I want to do X" cases, hooks handle the "whenever X happens, always do Y" cases.
Hook Types
Claude Code supports several hook trigger points. Each fires at a specific moment in the tool execution lifecycle:
- PreToolUse: Fires before Claude executes a tool (Bash, Edit, Write, etc.). Use this to block dangerous operations, validate inputs, or add logging before changes happen.
- PostToolUse: Fires after a tool completes. Use this to record what changed, run linters, update metrics, or trigger follow-up actions.
- SessionStart: Fires when a new Claude Code session begins. Use this to restore context, load memory files, or display a status dashboard.
- SessionEnd: Fires when a session ends. Use this to save state, write daily notes, or clean up temporary files.
- PreCompact: Fires before Claude compacts the conversation (when context gets too long). Use this to save critical state to disk before context is lost.
- PostCompact: Fires after compaction completes. Use this to reload essential context into the fresh conversation window.
Writing Your First Hook
Hooks are configured in .claude/settings.json under the hooks key. Each hook specifies a trigger type, an optional matcher (to filter which tools it applies to), and a command to execute:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "node .claude/hooks/validate-bash.js",
"description": "Block dangerous bash commands"
}
],
"SessionStart": [
{
"command": "cat .claude/memory.md",
"description": "Load memory on session start"
}
]
}
}The matcher field is optional. When present, the hook only fires for that specific tool. When absent, it fires for all tools of that trigger type. The command field runs a shell command — it can be a script, a CLI tool, or any executable.
Safety Hooks
The highest-value hooks are safety hooks — they prevent Claude from doing things that could damage your project:
- Block destructive commands: A PreToolUse hook on Bash that rejects
rm -rf,git push --force,DROP TABLE, and other dangerous patterns - Validate file edits: A PreToolUse hook on Edit that blocks modifications to critical files like
.env,package-lock.json, or production configs - Prevent secret leaks: A PostToolUse hook on Write that scans new file content for API keys, tokens, and credentials before they get committed
- Enforce branch rules: A PreToolUse hook on Bash that blocks direct commits to
mainorproductionbranches
Safety hooks give you confidence to let Claude work autonomously. They act as programmatic guardrails that enforce your team's policies regardless of what instructions Claude receives.
Intelligence Hooks
Beyond safety, hooks can make your AI brain smarter over time:
- Edit tracker: A PostToolUse hook on Edit that logs every file modification with timestamps, building a changelog you can review
- Metrics collector: A PostToolUse hook that counts tool calls, tracks session duration, and records which files Claude touches most
- Context preloader: A SessionStart hook that loads relevant memory files, recent git history, and project status so Claude starts every session fully informed
- State saver: A PreCompact hook that writes the current task, progress, and next steps to disk before context compaction erases them
- Task router: A PreToolUse hook that detects the type of work being done (coding, writing, research) and loads the appropriate agent configuration
Intelligence hooks turn your AI brain into a learning system. Every session generates data that makes the next session more effective.
Practical Exercise
Set up these three hooks to protect and enhance your codebase:
- Dangerous command blocker: Create a PreToolUse hook for Bash that rejects commands containing
rm -rf /,git push --force, orDROP DATABASE. Write a simple script that reads stdin, checks for these patterns, and exits with code 1 to block execution. - Session context loader: Create a SessionStart hook that prints the contents of your memory.md and the last 5 git commits so Claude always starts with full context.
- PreCompact state saver: Create a PreCompact hook that saves the current date, active task, and recent file changes to a recovery file at
.claude/recovery.mdso nothing is lost during context compaction.
Want pre-configured hooks that work out of the box?
The AI Brain Pro package includes 12 production-tested hooks covering safety, intelligence, context management, and automated quality checks.
View Pricing