ClaudeClaude

Hooks in Claude Code

deterministic hooks automate, log, and block actions in Claude Code.

May 7, 20263mWatch on YouTube ↗
Deterministic vs prompt-based behaviorHook lifecycle events (submit, pre/post tool use, notification, stop)Tool matchers (edit, multi-edit)Auto-formatting after editsCompliance logging of executed commandsBlocking dangerous operations with exit codesRepo-wide, team-shared configuration via .claude/settings.json
AI-generated summary based on the episode transcript.

In this episode of Claude, Hooks in Claude Code explores deterministic hooks automate, log, and block actions in Claude Code Hooks are deterministic lifecycle triggers that run every time, unlike prompt instructions that Claude may occasionally miss.

At a glance

WHAT IT’S REALLY ABOUT

Deterministic hooks automate, log, and block actions in Claude Code

  1. Hooks are deterministic lifecycle triggers that run every time, unlike prompt instructions that Claude may occasionally miss.
  2. Hooks are configured in a project's settings.json by selecting an event, optionally scoping with a tool matcher, and specifying a command to execute.
  3. Post-tool-use hooks commonly implement automatic formatting after file edits by running formatters based on file extension.
  4. Pre-tool-use hooks can enforce hard safety rules by blocking tool calls when a script exits with code 2 and returning a reason to Claude via stderr.
  5. Project-level hooks stored in .claude/settings.json can be checked into a repo so an entire team shares the same guaranteed behaviors across environments.

IDEAS WORTH REMEMBERING

5 ideas

Use hooks for guarantees, not suggestions.

Prompt instructions (e.g., “run prettier after edits”) may be skipped occasionally, but hooks always run at the configured lifecycle point with no exceptions.

Pick the hook event based on when you need control.

Use user-prompt-submit before Claude processes input, pre-tool-use to gate tool calls, post-tool-use to react after a tool finishes, notification on notifications, and stop when Claude completes its response.

Auto-formatting is best implemented as a post-tool-use hook.

Match on edit/multi-edit so the hook runs whenever files change, then route to the right formatter (Prettier, gofmt, Ruff, etc.) based on file extension.

Pre-tool-use hooks enable enforceable safety policies.

Your hook receives the tool name and JSON input on stdin; exit code 0 allows execution, while exit code 2 blocks it and returns an stderr message that Claude uses as corrective feedback.

Blocking rules can target high-risk actions precisely.

Examples include preventing writes to production config directories, stopping batch commands containing risky patterns like rm -rf, or blocking commits to main—rules your team wants guaranteed, not merely recommended.

WORDS WORTH SAVING

5 quotes

Hooks let you run commands at different points in Claude Code's lifecycle.

Unknown

The key difference between hooks and everything else we covered is that hooks are deterministic. They always run.

Unknown

But a hook makes it happen every single time with no exceptions.

Unknown

This is how you enforce hard rules.

Unknown

If something needs to happen every time without fail, don't put it in a prompt. Put it in a hook.

Unknown

QUESTIONS ANSWERED IN THIS EPISODE

5 questions

Which hook event should I choose if I want to validate user prompts (e.g., block secrets) before Claude processes them—user-prompt-submit or pre-tool-use, and why?

Hooks are deterministic lifecycle triggers that run every time, unlike prompt instructions that Claude may occasionally miss.

Can you show a concrete post-tool-use hook script that detects file extensions and runs Prettier for TS/JS and gofmt for Go in one command flow?

Hooks are configured in a project's settings.json by selecting an event, optionally scoping with a tool matcher, and specifying a command to execute.

What does the JSON payload sent to a pre-tool-use hook typically look like (tool name + input), and how should a script safely parse it?

Post-tool-use hooks commonly implement automatic formatting after file edits by running formatters based on file extension.

How do you recommend implementing a robust rm -rf detector that avoids false positives (e.g., in comments or strings) while still blocking truly dangerous commands?

Pre-tool-use hooks can enforce hard safety rules by blocking tool calls when a script exits with code 2 and returning a reason to Claude via stderr.

If a pre-tool-use hook blocks an action with exit code 2, what are best practices for the stderr message so Claude can reliably adjust its plan?

Project-level hooks stored in .claude/settings.json can be checked into a repo so an entire team shares the same guaranteed behaviors across environments.

Chapter Breakdown

Why hooks matter: deterministic behavior vs prompts

Hooks run commands at specific points in Claude Code’s lifecycle, and the defining advantage is determinism: they always run. This contrasts with instructions in claude.md, which may be followed most of the time but aren’t guaranteed.

Practical use cases for hooks (formatting, compliance, safety, alerts)

The video outlines common scenarios where deterministic execution is valuable. These include code quality automation, audit/compliance logging, preventing risky actions, and notifying users when work completes.

Where hooks are configured and what a hook contains

Hooks are configured in settings.json, where you select an event, optionally scope it with a matcher, and define a command to run. This structure makes hook behavior explicit and repeatable.

Hook events overview: when hooks fire in the lifecycle

Several lifecycle events are available to attach hooks to, covering user prompts, tool execution boundaries, notifications, and completion. Choosing the right event determines whether the hook runs before, after, or around Claude’s actions.

Auto-formatting pattern with post_tool_use (edits and multi-edits)

A common recipe is to run formatters after Claude modifies files by attaching a post_tool_use hook to edit-related tools. The hook can inspect file extensions and invoke the project’s appropriate formatter per language.

Enforcing hard rules with pre_tool_use (blocking tool calls)

Pre-tool hooks can prevent risky actions by intercepting tool calls before they execute. The hook receives the tool name and input via JSON on stdin, enabling policy checks and enforcement.

Exit codes and feedback loop: proceed vs block with explanation

Blocking is controlled through exit codes: success allows the action to continue, while a specific code blocks it. When blocked, stderr becomes feedback to Claude so it can adjust its plan to comply with the rules.

Examples of policies to block (production paths, rm -rf, main commits)

The video gives concrete examples of what teams may want to forbid deterministically. These include restricting writes to production configuration, rejecting destructive shell patterns, and preventing commits directly to protected branches.

Project-level hooks in .claude/settings.json for team-wide consistency

Hooks can be defined at the project level so they’re shared across a repository. Checking them in ensures everyone on the team gets the same deterministic behavior without manual setup.

Portable hook commands: using the Claude project dir environment variable

To make hook commands robust regardless of working directory, the video recommends referencing scripts via the Claude project directory environment variable. This allows hooks to call project-contained scripts reliably.

Decision rule: if it must happen every time, put it in a hook

The closing message is a rule of thumb for automation design in Claude Code. Use post_tool_use for actions like formatting/logging, pre_tool_use for safety blocks, and prefer hooks over prompts for guaranteed behavior.

EVERY SPOKEN WORD

Install uListen for AI-powered chat & search across the full episode — Get Full Transcript

Get more out of YouTube videos.

High quality summaries for YouTube videos. Accurate transcripts to search & find moments. Powered by ChatGPT & Claude AI.

Add to Chrome