⚡ Claude Code Feature Guide

Claude Code Hooks:
Automate Everything.

Hooks are shell commands Claude Code runs at lifecycle events — before each prompt, after each response, around every tool call. Most Claude Code users have never configured one. Here's everything you need.

Read the Guide → Full Claude Code Guide
In this guide

What are Claude Code Hooks?

Claude Code hooks are shell commands that run automatically at specific points in Claude's lifecycle. Think of them as event listeners — but instead of JavaScript callbacks, you're running real terminal commands.

They're configured in your Claude settings file and run outside Claude's awareness. Claude can't override them, can't see their output unless you pass it back in, and can't prevent them from running. They're yours.

Why hooks matter

Without hooks, Claude Code is an interactive session that starts when you type and ends when you close the terminal. With hooks, it becomes an automated workflow engine — logging every decision, running tests on every change, committing code on every exit, and blocking dangerous commands before they execute.

Hooks are a relatively new Claude Code feature that most users haven't explored. Engineers who use them describe their sessions as fundamentally different — the AI becomes a first-class part of their development pipeline, not just a conversation window.

The 5 Hook Types

Claude Code supports five lifecycle events. Each maps to a specific moment in how Claude processes your work.

UserPromptSubmit

Before each prompt

Fires when you press Enter, before Claude sees your message. Use for logging, context injection, or pre-validation of what you're about to ask.

Stop

After each response

Fires when Claude finishes responding or when the session ends. The most popular hook — use for git commits, summaries, notifications, and cleanup.

PreToolUse

Before tool calls

Fires before Claude calls any tool (Bash, Read, Write, Edit, etc.). You can inspect the tool name and input — and block execution by returning a non-zero exit code.

PostToolUse

After tool calls

Fires after a tool call completes. Use for linting after file writes, running tests after code changes, or logging what Claude actually modified.

PreCompact

Before context compaction

Fires before Claude compresses your conversation to stay within context limits. Use to archive the full transcript or checkpoint your session state.

Hook When it runs Can block? Primary use
UserPromptSubmit On every message you send No Logging, analytics, context prep
Stop After each Claude response / session end No Git commits, notifications, summaries
PreToolUse Before every tool call Yes Safety gates, dangerous command blocking
PostToolUse After every tool call No Lint, test, format, backup verification
PreCompact Before context compaction No Transcript archiving, state checkpointing

How to Configure Hooks

Hooks are configured in Claude's settings file. There are two places to put them:

The basic structure is an object with hook type names as keys, each containing an array of hook configurations:

~/.claude/settings.json — minimal example
{ "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "echo '[Claude stopped at '$(date)']' >> ~/claude_sessions.log" } ] } ] } }

To target specific tools with PreToolUse/PostToolUse, use the matcher field. It matches against the tool name using a substring or regex pattern:

PreToolUse with matcher — runs only before Bash calls
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "/usr/local/bin/check_dangerous_commands.sh" } ] } ] } }
Important: exit codes

For PreToolUse hooks, a non-zero exit code blocks the tool call. Claude will see a message that the hook blocked execution. Use this to build safety gates. For all other hooks, exit codes are informational only.

Hook commands receive context via environment variables and stdin. The exact variables depend on the hook type — for PreToolUse, you get the tool name and input JSON. For UserPromptSubmit, you get the message text.

UserPromptSubmit with environment variables
{ "hooks": { "UserPromptSubmit": [ { "hooks": [ { "type": "command", "command": "echo \"[$(date '+%Y-%m-%dT%H:%M:%S')] $CLAUDE_USER_PROMPT\" >> ~/claude_prompt_log.txt" } ] } ] } }

15 Real-World Hook Configurations

The following examples are taken from production Claude Code setups across different workflows. Copy, adapt, and combine them.

01 — Stop hook

Auto-commit on every session end

Runs git add -A && git commit automatically when Claude exits. Never lose session work.

02 — UserPromptSubmit

Prompt log for conversation history

Appends every user message to a JSONL log with timestamp. Powers conversation history dashboards.

03 — PostToolUse / Write

Run ESLint after file writes

Matcher: "Write". Runs eslint --fix on the written file automatically.

04 — PostToolUse / Edit

Run tests after code changes

Matcher: "Edit". Runs your test suite after every code edit. Instant feedback loop.

05 — PreToolUse / Bash

Block rm -rf commands

Parses the bash command. Exits 1 (blocking) if it contains dangerous delete patterns.

06 — Stop hook

Desktop notification when done

Sends an osascript notification on macOS when Claude finishes a long task.

07 — PreCompact

Archive full session transcript

Before context compaction, saves the full conversation to a timestamped file. Never lose session context.

08 — PostToolUse / Write

Auto-format with Prettier

Matcher: "Write". Runs prettier --write on every file Claude creates. Consistent style, zero effort.

09 — UserPromptSubmit

Inject current git status into context

Prepends git status output before every prompt. Claude always knows the current branch state.

10 — Stop hook

Post session summary to Slack

Uses Claude to summarize the session's changes, then posts to a Slack webhook. Team visibility without manual updates.

11 — PreToolUse / Bash

Require approval for production commands

Blocks commands targeting production environments and prompts for manual approval.

12 — PostToolUse / Write

Create backup before every write

Copies original file to *.bak.{timestamp} before Claude writes over it. One-command rollback.

13 — UserPromptSubmit

Count session tokens (cost tracker)

Estimates tokens per message and accumulates a session cost estimate. Know exactly what each session costs.

14 — PostToolUse / Bash

Log all commands run

Appends every bash command Claude runs to an audit log. Full traceability for review.

15 — Stop hook

Deploy on exit (CI trigger)

Runs python3 deploy.py on session end. Each Claude session becomes a mini deployment pipeline.

Full Example: Auto-Commit + Notification Setup

This is a common starting configuration for engineers who want Claude to feel like a real team member — changes saved, team notified, nothing lost.

~/.claude/settings.json — auto-commit + notification
{ "hooks": { "Stop": [ { "hooks": [ { "type": "command", "command": "cd $(git rev-parse --show-toplevel 2>/dev/null || echo '.') && git diff --quiet && git diff --staged --quiet || git add -A && git commit -m 'auto: claude session $(date +%Y%m%d_%H%M%S)' --no-gpg-sign 2>/dev/null || true" }, { "type": "command", "command": "osascript -e 'display notification \"Claude Code session ended\" with title \"Done\"' 2>/dev/null || true" } ] } ], "UserPromptSubmit": [ { "hooks": [ { "type": "command", "command": "echo \"{\\\"time\\\":\\\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\\\",\\\"role\\\":\\\"user\\\",\\\"content\\\":\\\"$(echo \"$CLAUDE_USER_PROMPT\" | head -c 500 | tr '\"' \"'\" | tr '\\n' ' ')\\\"}\" >> ~/claude_messages.jsonl" } ] } ] } }

Safety Hooks: Blocking Dangerous Commands

PreToolUse hooks are the only hook type that can actively block Claude. When your hook script exits with a non-zero code, Claude receives a message that the tool call was blocked and can try an alternative approach.

This makes PreToolUse the right place to put guardrails — especially for Bash commands, which can do irreversible damage.

check_dangerous.sh — block rm -rf, force push, DROP TABLE
#!/bin/bash # Save to ~/bin/check_dangerous.sh and chmod +x COMMAND="$CLAUDE_TOOL_INPUT" # Block dangerous delete patterns if echo "$COMMAND" | grep -qE 'rm\s+-rf\s+/|rm\s+-rf\s+\*|rm\s+-rf\s+~'; then echo "BLOCKED: Recursive delete on root/home detected" >&2 exit 1 fi # Block git force push to main/master if echo "$COMMAND" | grep -qE 'git push.*--force.*main|git push.*--force.*master'; then echo "BLOCKED: Force push to protected branch" >&2 exit 1 fi # Block SQL DROP TABLE on production databases if echo "$COMMAND" | grep -qi 'DROP TABLE\|DROP DATABASE\|TRUNCATE'; then echo "BLOCKED: Destructive SQL detected — run manually if intentional" >&2 exit 1 fi exit 0
settings.json — wire the safety script
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "~/bin/check_dangerous.sh" } ] } ] } }
Building a safety hook library

Good safety hooks are specific, not blanket "ask me first" gates. Blanket confirmation fatigue gets bypassed. Specific pattern matching for actually dangerous commands (root deletes, production pushes, DROP statements) blocks real risks without interrupting normal work.

Brainfile Hook Templates

Configuring hooks from scratch takes time — you need to understand shell escaping, exit code semantics, environment variable availability, and the right matcher patterns for each tool. Brainfile members get production-tested hook configurations for their role.

👨‍💻

Developer

Auto-commit, ESLint, Prettier, test runner, dangerous command blocker. Full safety + automation stack.

🚀

Founder / Solo Builder

Session logging, cost tracking, deploy-on-exit, Slack notification, weekly summary generation.

📊

Data Analyst

Query logging, output archiving, notebook checkpointing, safety gate for data deletion commands.

⚙️

DevOps / Platform

Production protection gates, audit logging, deploy approval workflow, config backup before writes.

✍️

Content Creator

Draft versioning, word count tracking, auto-backup before edits, publish pipeline trigger on stop.

🏢

Enterprise / Team

Centralized audit trail, team notification on changes, compliance logging, pre-approved command lists.

Get Hook Templates for Your Role — $149/mo →
Claude Code Automation Stack

Hooks are just the start.
Brainfile sets up the whole thing.

150+ role-specific templates: CLAUDE.md, .cursorrules, settings.json hooks, memory files, and automation scripts. Preconfigured for your profession. Updated monthly.

$149 /month

30-day money-back guarantee · Instant access · Cancel anytime

Need team setup? Enterprise at $299/mo →

Free: Claude Code Automation Recipes

New hook examples, CLAUDE.md patterns, and workflow automation ideas. Free weekly digest.

No spam. Unsubscribe anytime.