Skip to main content

How to Use Claude Code Hooks

Learn how Claude Code hooks work: shell commands that run automatically on events like PostToolUse and Stop to format code, block risky actions and more.

Hosna Kachooee By Hosna Kachooee Updated August 2026

Claude Code hooks let you run your own shell commands automatically at specific points in a session, so certain things always happen instead of depending on the model to choose them. They are great for formatting code after edits, sending a notification when Claude needs you, or blocking a risky command before it runs. Here is how they work.

What hooks are

A hook is a user-defined shell command that Claude Code runs when a particular event fires. This gives you deterministic control: the action happens every time, rather than relying on the model to decide. Common uses include auto-formatting edited files, injecting context at the start of a session, enforcing project rules and integrating Claude Code with your existing tools.

Each hook receives a JSON payload on standard input describing what just happened. That payload includes fields like session_id, cwd, hook_event_name and, for tool events, tool_name and tool_input. Your script can read those to decide what to do.

The hook events

Hooks fire on named lifecycle events. The most commonly used ones:

EventWhen it fires
PreToolUseBefore a tool call runs, and it can block the call
PostToolUseAfter a tool call succeeds, for example right after a file edit
UserPromptSubmitBefore Claude processes your prompt
NotificationWhen Claude Code sends a notification, such as needing your input
StopWhen Claude finishes responding
SubagentStopWhen a subagent finishes
SessionStartWhen a session begins or resumes
SessionEndWhen a session ends
PreCompactBefore Claude Code compacts the conversation context

Claude Code exposes more events than these, but the ones above cover most day-to-day setups. Use the exact event names as written when you add them to your settings.

Configuring a hook

Hooks live in a settings file. Use ~/.claude/settings.json for all your projects, .claude/settings.json to share with a project’s repo, or .claude/settings.local.json for personal settings you keep out of version control.

Here is a real, safe example: automatically run Prettier on any file Claude edits or writes. It uses the PostToolUse event with a matcher that targets the Edit and Write tools.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

The matcher decides which tool names trigger the hook. Edit|Write matches either tool, Bash matches only Bash, and leaving it empty or using * matches everything. The command reads the JSON on stdin, pulls out the edited file’s path with jq, and passes it to Prettier. After this is saved, every edit Claude makes gets formatted without you asking.

You can also open the hooks browser inside Claude Code by typing /hooks to see every event and confirm your hook is registered.

Blocking and exit codes

Hooks can do more than react: they can steer what happens next. For events like PreToolUse, an exit code of 2 blocks the action and sends the reason back to Claude, while exit code 0 lets it proceed. For richer control, a hook can print JSON to standard output with a permissionDecision of allow or deny and a reason, which is a clean way to stop destructive commands (for example, catching an rm -rf before it runs). Non-blocking events simply let the session continue.

A note on safety

Hooks run arbitrary shell commands on your machine, automatically, with your own permissions. That power is the point, but it means a careless or copied hook can do real damage. Only add hooks you understand, read through any configuration you take from someone else, and start with harmless actions like formatting or notifications before you write ones that block or rewrite commands. If you ever want to pause everything, you can disable all hooks in your settings while you debug.

Keep going

Hooks are one piece of getting Claude Code to fit your workflow. Explore the rest of the Claude Code hub, and if you are just getting set up, start with how to install Claude Code. From there, pair hooks with slash commands and permissions to shape how Claude behaves. To build the wider AI skills around all of this, our AI course covers working with AI tools, and you can start with the free lessons.

Frequently asked questions

What are Claude Code hooks?

Hooks are shell commands that Claude Code runs automatically at set points in its lifecycle, such as before a tool runs or after a file is edited. Because they always fire, they give you deterministic control instead of relying on the model to remember to do something.

Where do I configure Claude Code hooks?

In a settings file: ~/.claude/settings.json for all your projects, .claude/settings.json committed to a single project, or .claude/settings.local.json for personal, gitignored settings. Each hook lists an event name, an optional matcher and the command to run.

Are Claude Code hooks safe to use?

Hooks run arbitrary shell commands on your machine with your permissions, so treat them like any script you run yourself. Only add hooks you understand, review any config you copy from others, and start with harmless actions like formatting before blocking or modifying commands.

Start free

Get free access to our beginner courses

Drop your email and we'll let you know the moment each free course is live - plus new courses and deals. No spam, unsubscribe anytime.

Master Claude Code from start to finish

This is one lesson from a much larger course. Get the full course with a single one-time payment and lifetime access.

Explore our AI course