Skip to content
AI Dev Toolkit.
Esc
  • AI Token CounterCount tokens for GPT, Claude, Gemini, DeepSeek, Qwen and more.Tool
  • LLM API Cost CalculatorEstimate per-request, daily and monthly API costs.Tool
  • AI Model ComparisonCompare prices, context windows and features across models.Tool
  • AI Model Pricing PagesSpecs, real costs and cheaper alternatives for popular models.Tool
  • Context Window CheckerSee whether your text fits each model’s context window.Tool
  • Subscription vs API CalculatorFind out whether a chat plan or the API is cheaper for you.Tool
  • GPU / VRAM CalculatorCheck how much VRAM a local model needs and which GPUs fit.Tool
  • Prompt Caching CalculatorEstimate savings from prompt caching.Tool

AI glossary · Agents and tools

What are Claude Code hooks?

Also called: hooks, PreToolUse hook, lifecycle hooks

Definition

Claude Code hooks are commands, HTTP calls, MCP tool calls, prompts or subagents that Claude Code runs automatically at fixed points in a session, such as just before a tool call, so a rule is applied every time.

Explained

How it works

A hook pairs an event with a handler. Events include PreToolUse (before a tool runs), PostToolUse (after it succeeds), UserPromptSubmit, Stop and SessionStart, among many more. Handlers come in five types: command, http, mcp_tool, prompt and agent. On tool events, a matcher picks tool names and an optional if field narrows further with permission-rule syntax such as Bash(git *).

Hooks go under a hooks key in a settings file: ~/.claude/settings.json for all your projects, .claude/settings.json for one project (committed), or .claude/settings.local.json for just you. Plugins, skills and subagents can carry hooks too. A command hook receives the event as JSON on stdin. Exit code 0 means success; exit code 2 blocks the action on events that can block, and the hook’s stderr becomes the reason, which Claude sees on tool events such as PreToolUse; any other code is a non-blocking error.

Example

Block npm publish with exit code 2

Put this in .claude/settings.json. The if rule matches npm publish with or without arguments, because a trailing * also matches the bare command, so the hook runs only then. It prints a reason to stderr and exits 2: Claude Code cancels the tool call and shows Claude the reason, so it can take another route.

We ran the command in Bash: it printed the message to stderr and exited with code 2. It needs a POSIX shell such as Bash; on Windows without Git Bash, command hooks run in PowerShell, so write them for that shell.

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(npm publish *)",
            "command": "echo 'Releases are published by CI. Do not run npm publish.' >&2; exit 2"
          }
        ]
      }
    ]
  }
}

Cost and quality

Why it matters

Instructions in CLAUDE.md are context: Claude usually follows them, but nothing forces it to. Claude Code’s docs point to a PreToolUse hook when an action must be blocked whatever Claude decides. Hooks also take routine chores, such as formatting after each edit, out of the model’s hands.

A hook is code that runs on your machine whenever its event fires. Read the hooks in any repository before you trust its settings.

Don’t mix up

Common confusions

Hooks vs CLAUDE.md
CLAUDE.md tells Claude what you want, and Claude decides. A hook is run by Claude Code itself on every matching event, whatever Claude decides, and exit code 2 can stop an action outright.
Hooks vs permission rules
A permission rule such as a deny on Bash(npm publish *) also blocks a command, with no script. Use a hook when the decision needs logic, a message to Claude, or a side effect such as logging.

Go deeper

Try it and read more

Related

All 40 terms in the AI glossary