◉CLAUDE LABJP
●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/Claude Code
⟐ Claude Code/2026-04-27Advanced

Claude Code Hooks: A Field Guide to the 8 Core Hooks — and the 33-Event Catalog They Now Live In

Claude Code hooks are powerful, but most people give up before figuring out which event does what. Here's the field guide I wish I had when I started — six months of running hooks in production, distilled.

Claude Code264Hooks6Automation45Workflow8Practical GuideAgent Design

✦ Premium Article

I spent six months running Claude Code in production before I truly understood hooks. The documentation covers what they do, but not why you'd pick one over another in a real scenario. Halfway through, I realized I'd been setting up hooks wrong the whole time: two hooks fighting each other, one never firing because I'd misconfigured the timing, another creating an infinite loop.

The frustration wasn't the hooks themselves—it was the mental model. I was treating them like simple on/off switches when they're actually a control flow system that governs the entire conversation between you, Claude Code, and your tools.

This guide is for people who got hooks working once, then broke something and gave up. Or people who want to avoid that entirely. I'll walk through every hook type, show you when to use it, and reveal the three production bugs I hit that taught me the hard way.

The Design Philosophy Behind Hooks

Claude Code hooks aren't just event listeners. They're the connective tissue between what you ask Claude to do and what actually gets executed.

Think of the traditional flow: user prompt → code generation → done. One direction, no feedback loop.

Hooks create: user ⇄ Claude Code (with hooks) ⇄ tools (git, npm, shell, API calls). Bidirectional. The hook system manages that conversation. Each hook type handles a specific phase.

The first principle: separate concerns. Don't put PostToolUse logic in PreToolUse. Don't use Stop to handle single-tool failures. Mixing them is where everything breaks.

The second: hooks are synchronous by default, but support async. If you put a Promise in a hook, Claude Code will wait. But wait too long and the session times out. The balance is tight—that's our first production trap.

The third: hooks fire in sequence, not in parallel. Misunderstanding this sequence is the most common footgun. Get this wrong and you'll spend hours debugging why a value is undefined or why a tool runs twice.

The fourth: each hook phase has a different responsibility. Don't make SessionStart do what SessionEnd should do. Don't make PreToolUse handle post-execution validation. This separation is what makes debugging possible.

The 8 Core Hooks: A Reference Map

A quick note on scope before the table. When this article was first published, these eight were the main events hooks offered. The catalog has grown a lot since — the official reference now lists 33 events as of late August 2026 — and I cover how to navigate that expansion in two later sections. The eight below are still the backbone, and everything else is easier to place once you know them.

HookFiresResponsibilityCommon Use
SessionStartImmediately after session beginsInitialize environmentSet up dependencies, env files, initial checks
UserPromptSubmitWhen user sends a message (before processing)Pre-filter and enrich inputDetect code, validate syntax, security checks
PreToolUseRight before a tool executesValidate preconditionsSecurity gates, permission checks, state validation
PostToolUseRight after a tool executesVerify resultsConfirm success, handle errors, log outcomes
NotificationWhen Claude Code itself raises a notificationRelay waiting statesForward permission prompts and idle prompts off-screen
StopRight before Claude ends its turnWithhold the endingRefuse to stop while work is unfinished
SubagentStopRight before a subagent endsWithhold the subagent's endingSend a subagent back for work it skipped
SessionEndBefore session closesFinal cleanupGenerate reports, archive logs, notifications

This table is deceptive because it makes them look independent. They're not. Understanding the firing sequence is the foundation of hooks that actually work.

One note about the JSON in this guide. Three sections — PreToolUse vs PostToolUse, UserPromptSubmit, and the SessionStart/SessionEnd pair — use a conceptual pseudo-schema to make each hook's responsibility obvious; those blocks won't run as written. Everything from Stop/SubagentStop onward is real: the notification hook, model switching, the three traps, the templates, the config section, and the exit-code section all show configs and scripts running on my machine. If you want something you can paste and run, skip ahead.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦The real hooks config format in settings.json — matcher, command, the stdin JSON contract, and exit code 2 to block — not the conceptual pseudo-schema
✦A map of the hook catalog as of August 2026 — 33 events — plus working PreModelSwitch / PostModelSwitch configs (v2.1.251) that turn model switches into enforceable policy
✦Measured per-tool overhead that hooks add, and the latency budget that keeps them from getting in the way
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⟐ Claude Code2026-09-01
Drop the quotes on a heredoc and the prices in your log quietly change
An unquoted heredoc runs the variables and backticks inside its body. Here are the four ways my log got rewritten, how the three quoting forms compare, a safe placeholder-and-sed pattern, and a small script for auditing what you already have.
⟐ Claude Code2026-08-22
Handing a long job to another session — and the completion marker for when the notification never arrives
How to use notify_when_idle to hear when another Claude Code session finishes, and a small completion marker that keeps you from waiting forever when the notification is dropped.
⟐ Claude Code2026-08-03
Existence Checks Pass, Writes Fail — Probing Capabilities Before an Unattended Run
A directory existing and a directory being writable are two different facts. Measured results from five broken-environment cases, why static clues cannot predict the worst of them, and a capability-probe preflight for unattended Claude Code runs.