Claude Code · Hooks

Claude Code Hooks

Hooks turn good intentions into guarantees. Here's how they work, which ones are worth setting up, and how to use one to load your team's shared context on every session.

Most of what you tell an agent is a request — the model can follow it or not. Hooks are different: they're code Claude Code runs automatically at fixed points, every time. If something must happen — a file gets formatted, a protected path stays protected, shared context gets loaded — a hook is how you guarantee it.

What a hook is

A hook is a shell command bound to a lifecycle event. When the event fires, Claude Code runs your command, optionally passes it details about what's happening, and uses the result to decide what to do next. Because it's just a shell command, a hook can do anything your shell can: run a formatter, call a linter, hit an API, print context, reject an action.

The lifecycle events

EventFires whenCommon use
SessionStartA new session beginsInject shared context, print project state
PreToolUseBefore the agent runs a toolGuardrails — block edits to protected paths or risky commands
PostToolUseAfter a tool runsFormat on edit, run a check, log the change
StopThe agent finishes respondingNotifications, cleanup, summary

The exact event set evolves with Claude Code, but the shape is stable: something happens, your hook runs, its exit code and output steer the agent.

Hooks worth setting up

  • Format on edit (PostToolUse). Run your formatter after every file write so the agent's output always matches your style — no reminders needed.
  • Protect critical paths (PreToolUse). Reject edits to lockfiles, generated code, or infrastructure config unless explicitly intended.
  • Guard dangerous commands (PreToolUse). Block force-push, destructive deletes, or prod operations behind a confirmation.
  • Notify on completion (Stop). Ping yourself when a long-running task finishes.

The context hook: load shared knowledge on every session

The single highest-value hook for a team is a SessionStart hook that loads your shared context. Instead of relying on each developer's local CLAUDE.md — which drifts — you print the team's decisions, conventions, and ownership at the top of every session, so the agent always reasons from the same source of truth.

Conceptually, the hook just emits your context to stdout:

# .claude/settings.json (SessionStart hook, simplified)
{
  "hooks": {
    "SessionStart": [
      { "command": "first-tree inject --for $CLAUDE_PROJECT_DIR" }
    ]
  }
}

The command reads the relevant nodes from your context tree and prints them; Claude Code folds that into the session. Every agent — yours and your teammates' — starts already knowing what your team has decided.

This is how First-Tree plugs into Claude Code.

First-Tree is an open-source platform for engineering teams shipping with humans and agents side by side: agents chat alongside you in shared threads, GitHub issues and PRs become the queue the right agent picks up, and a living context tree of decisions, designs, and ownership keeps every agent on the same page. The hook is the on-ramp for that last pillar — a SessionStart hook injects the right nodes into each Claude Code session, so shared memory loads automatically instead of living in per-developer files that fall out of sync. See Claude Code best practices for how this fits the rest of a team setup.

Gotchas

  • Hooks run every time — keep them fast. A slow SessionStart or PostToolUse hook taxes every interaction. Cache where you can.
  • Mind blocking vs non-blocking. A PreToolUse hook that blocks should fail clearly; a formatting hook shouldn't halt the agent on a non-fatal warning.
  • Exit codes matter. The hook's exit status is the signal Claude Code reads. Return success/failure deliberately.

Hooks pair naturally with MCP servers (for tool access) and subagents (for scoped work). Together they're how you run Claude Code as a team rather than a collection of disconnected sessions.

FAQ

Common questions.

What are Claude Code hooks?

Hooks are shell commands Claude Code runs automatically at defined points in its lifecycle — before or after a tool call, when a session starts, when it stops. They let you enforce deterministic behavior (formatting, guardrails, context injection) instead of hoping the agent remembers to do it.

What's the difference between a hook and an instruction in CLAUDE.md?

A CLAUDE.md instruction is a request the model may or may not follow. A hook is code that runs every time, no matter what the model decides. Use CLAUDE.md for guidance and hooks for guarantees — anything that must happen belongs in a hook.

Can a hook block an action?

Yes. A PreToolUse hook can inspect what the agent is about to do and reject it — for example, refusing edits to a protected path or blocking a destructive command. The hook's exit code tells Claude Code whether to proceed.

How do I load shared team context with a hook?

Use a SessionStart hook that prints your team's context — for example, the relevant nodes from a context tree — so every session begins with your team's decisions already in view. This is how First-Tree integrates with Claude Code.

Get Started

Run your agents on First-Tree.

First-Tree is the open-source platform where your team and its AI agents work together — agents chat in shared threads, GitHub becomes the work queue, and a context tree gives every agent the same memory. Start in your repo in one command.