---
title: "Run your setup commands that modify the environment"
description: "[Skip to main content](https://code.claude.com/docs/en/hooks#content-area)"
type: skill
canonical_url: https://claudary.paisolsolutions.com/skills/claude-code-hooks-docs
source: "Claudary"
difficulty: intermediate
author: "Claude Code Knowledge Pack"
date: 2026-07-10T11:13:58.598Z
license: CC-BY-4.0
attribution: "Run your setup commands that modify the environment — Claudary (https://claudary.paisolsolutions.com/skills/claude-code-hooks-docs)"
---

# Run your setup commands that modify the environment
[Skip to main content](https://code.claude.com/docs/en/hooks#content-area)

## Overview

[Skip to main content](https://code.claude.com/docs/en/hooks#content-area)

[Claude Code Docs home page![light logo](https://mintcdn.com/claude-code/o69F7a6qoW9vboof/logo/light.svg?fit=max&auto=format&n=o69F7a6qoW9vboof&q=85&s=536eade682636e84231afce2577f9509)![dark logo](https://mintcdn.com/claude-code/o69F7a6qoW9vboof/logo/dark.svg?fit=max&auto=format&n=o69F7a6qoW9vboof&q=85&s=0766b3221061e80143e9f300733e640b)](https://code.claude.com/docs)

![US](https://d3gk2c5xim1je2.cloudfront.net/flags/US.svg)

English

Search...

⌘KAsk AI

Search...

Navigation

Reference

Hooks reference

[Getting started](https://code.claude.com/docs/en/overview) [Build with Claude Code](https://code.claude.com/docs/en/sub-agents) [Deployment](https://code.claude.com/docs/en/third-party-integrations) [Administration](https://code.claude.com/docs/en/setup) [Configuration](https://code.claude.com/docs/en/settings) [Reference](https://code.claude.com/docs/en/cli-reference) [Resources](https://code.claude.com/docs/en/legal-and-compliance)

On this page

- [Hook lifecycle](https://code.claude.com/docs/en/hooks#hook-lifecycle)
- [Configuration](https://code.claude.com/docs/en/hooks#configuration)
- [Structure](https://code.claude.com/docs/en/hooks#structure)
- [Project-Specific Hook Scripts](https://code.claude.com/docs/en/hooks#project-specific-hook-scripts)
- [Plugin hooks](https://code.claude.com/docs/en/hooks#plugin-hooks)
- [Hooks in skills and agents](https://code.claude.com/docs/en/hooks#hooks-in-skills-and-agents)
- [Prompt-Based Hooks](https://code.claude.com/docs/en/hooks#prompt-based-hooks)
- [How prompt-based hooks work](https://code.claude.com/docs/en/hooks#how-prompt-based-hooks-work)
- [Configuration](https://code.claude.com/docs/en/hooks#configuration-2)
- [Response schema](https://code.claude.com/docs/en/hooks#response-schema)
- [Supported hook events](https://code.claude.com/docs/en/hooks#supported-hook-events)
- [Example: Intelligent Stop hook](https://code.claude.com/docs/en/hooks#example%3A-intelligent-stop-hook)
- [Example: SubagentStop with custom logic](https://code.claude.com/docs/en/hooks#example%3A-subagentstop-with-custom-logic)
- [Comparison with bash command hooks](https://code.claude.com/docs/en/hooks#comparison-with-bash-command-hooks)
- [Best practices](https://code.claude.com/docs/en/hooks#best-practices)
- [Hook Events](https://code.claude.com/docs/en/hooks#hook-events)
- [PreToolUse](https://code.claude.com/docs/en/hooks#pretooluse)
- [PermissionRequest](https://code.claude.com/docs/en/hooks#permissionrequest)
- [PostToolUse](https://code.claude.com/docs/en/hooks#posttooluse)
- [Notification](https://code.claude.com/docs/en/hooks#notification)
- [UserPromptSubmit](https://code.claude.com/docs/en/hooks#userpromptsubmit)
- [Stop](https://code.claude.com/docs/en/hooks#stop)
- [SubagentStop](https://code.claude.com/docs/en/hooks#subagentstop)
- [PreCompact](https://code.claude.com/docs/en/hooks#precompact)
- [Setup](https://code.claude.com/docs/en/hooks#setup)
- [SessionStart](https://code.claude.com/docs/en/hooks#sessionstart)
- [Persisting environment variables](https://code.claude.com/docs/en/hooks#persisting-environment-variables)
- [SessionEnd](https://code.claude.com/docs/en/hooks#sessionend)
- [Hook Input](https://code.claude.com/docs/en/hooks#hook-input)
- [PreToolUse Input](https://code.claude.com/docs/en/hooks#pretooluse-input)
- [Bash tool](https://code.claude.com/docs/en/hooks#bash-tool)
- [Write tool](https://code.claude.com/docs/en/hooks#write-tool)
- [Edit tool](https://code.claude.com/docs/en/hooks#edit-tool)
- [Read tool](https://code.claude.com/docs/en/hooks#read-tool)
- [PostToolUse Input](https://code.claude.com/docs/en/hooks#posttooluse-input)
- [Notification Input](https://code.claude.com/docs/en/hooks#notification-input)
- [UserPromptSubmit Input](https://code.claude.com/docs/en/hooks#userpromptsubmit-input)
- [Stop Input](https://code.claude.com/docs/en/hooks#stop-input)
- [SubagentStop Input](https://code.claude.com/docs/en/hooks#subagentstop-input)
- [PreCompact Input](https://code.claude.com/docs/en/hooks#precompact-input)
- [Setup Input](https://code.claude.com/docs/en/hooks#setup-input)
- [SessionStart Input](https://code.claude.com/docs/en/hooks#sessionstart-input)
- [SubagentStart Input](https://code.claude.com/docs/en/hooks#subagentstart-input)
- [SessionEnd Input](https://code.claude.com/docs/en/hooks#sessionend-input)
- [Hook Output](https://code.claude.com/docs/en/hooks#hook-output)
- [Simple: Exit Code](https://code.claude.com/docs/en/hooks#simple%3A-exit-code)
- [Exit Code 2 Behavior](https://code.claude.com/docs/en/hooks#exit-code-2-behavior)
- [Advanced: JSON Output](https://code.claude.com/docs/en/hooks#advanced%3A-json-output)
- [Common JSON Fields](https://code.claude.com/docs/en/hooks#common-json-fields)
- [PreToolUse Decision Control](https://code.claude.com/docs/en/hooks#pretooluse-decision-control)
- [PermissionRequest Decision Control](https://code.claude.com/docs/en/hooks#permissionrequest-decision-control)
- [PostToolUse Decision Control](https://code.claude.com/docs/en/hooks#posttooluse-decision-control)
- [UserPromptSubmit Decision Control](https://code.claude.com/docs/en/hooks#userpromptsubmit-decision-control)
- [Stop/SubagentStop Decision Control](https://code.claude.com/docs/en/hooks#stop%2Fsubagentstop-decision-control)
- [Setup Decision Control](https://code.claude.com/docs/en/hooks#setup-decision-control)
- [SessionStart Decision Control](https://code.claude.com/docs/en/hooks#sessionstart-decision-control)
- [SessionEnd Decision Control](https://code.claude.com/docs/en/hooks#sessionend-decision-control)
- [Exit Code Example: Bash Command Validation](https://code.claude.com/docs/en/hooks#exit-code-example%3A-bash-command-validation)
- [JSON Output Example: UserPromptSubmit to Add Context and Validation](https://code.claude.com/docs/en/hooks#json-output-example%3A-userpromptsubmit-to-add-context-and-validation)
- [JSON Output Example: PreToolUse with Approval](https://code.claude.com/docs/en/hooks#json-output-example%3A-pretooluse-with-approval)
- [Working with MCP Tools](https://code.claude.com/docs/en/hooks#working-with-mcp-tools)
- [MCP Tool Naming](https://code.claude.com/docs/en/hooks#mcp-tool-naming)
- [Configuring Hooks for MCP Tools](https://code.claude.com/docs/en/hooks#configuring-hooks-for-mcp-tools)
- [Examples](https://code.claude.com/docs/en/hooks#examples)
- [Security Considerations](https://code.claude.com/docs/en/hooks#security-considerations)
- [Disclaimer](https://code.claude.com/docs/en/hooks#disclaimer)
- [Security Best Practices](https://code.claude.com/docs/en/hooks#security-best-practices)
- [Configuration Safety](https://code.claude.com/docs/en/hooks#configuration-safety)
- [Hook Execution Details](https://code.claude.com/docs/en/hooks#hook-execution-details)
- [Debugging](https://code.claude.com/docs/en/hooks#debugging)
- [Basic Troubleshooting](https://code.claude.com/docs/en/hooks#basic-troubleshooting)
- [Advanced Debugging](https://code.claude.com/docs/en/hooks#advanced-debugging)
- [Debug Output Example](https://code.claude.com/docs/en/hooks#debug-output-example)

For a quickstart guide with examples, see [Get started with Claude Code hooks](https://code.claude.com/docs/en/hooks-guide).

## [​](https://code.claude.com/docs/en/hooks\\#hook-lifecycle)  Hook lifecycle

Hooks fire at specific points during a Claude Code session.

![Hook lifecycle diagram showing the sequence of hooks from SessionStart through the agentic loop to SessionEnd](https://mintcdn.com/claude-code/z2YM37Ycg6eMbID3/images/hooks-lifecycle.png?fit=max&auto=format&n=z2YM37Ycg6eMbID3&q=85&s=5c25fedbc3db6f8882af50c3cc478c32)

| Hook | When it fires |
| --- | --- |
| `SessionStart` | Session begins or resumes |
| `UserPromptSubmit` | User submits a prompt |
| `PreToolUse` | Before tool execution |
| `PermissionRequest` | When permission dialog appears |
| `PostToolUse` | After tool succeeds |
| `PostToolUseFailure` | After tool fails |
| `SubagentStart` | When spawning a subagent |
| `SubagentStop` | When subagent finishes |
| `Stop` | Claude finishes responding |
| `PreCompact` | Before context compaction |
| `SessionEnd` | Session terminates |
| `Notification` | Claude Code sends notifications |

## [​](https://code.claude.com/docs/en/hooks\\#configuration)  Configuration

Claude Code hooks are configured in your [settings files](https://code.claude.com/docs/en/settings):

- `~/.claude/settings.json` \\- User settings
- `.claude/settings.json` \\- Project settings
- `.claude/settings.local.json` \\- Local project settings (not committed)
- Managed policy settings

Enterprise administrators can use `allowManagedHooksOnly` to block user, project, and plugin hooks. See [Hook configuration](https://code.claude.com/docs/en/settings#hook-configuration).

### [​](https://code.claude.com/docs/en/hooks\\#structure)  Structure

Hooks are organized by matchers, where each matcher can have multiple hooks:

Copy

Ask AI

```
{
  "hooks": {
    "EventName": [\\
      {\\
        "matcher": "ToolPattern",\\
        "hooks": [\\
          {\\
            "type": "command",\\
            "command": "your-command-here"\\
          }\\
        ]\\
      }\\
    ]
  }
}
```

- **matcher**: Pattern to match tool names, case-sensitive (only applicable for
`PreToolUse`, `PermissionRequest`, and `PostToolUse`)
  - Simple strings match exactly: `Write` matches only the Write tool
  - Supports regex: `Edit|Write` or `Notebook.*`
  - Use `*` to match all tools. You can also use empty string (`""`) or leave
    `matcher` blank.
- **hooks**: Array of hooks to execute when the pattern matches
  - `type`: Hook execution type - `"command"` for bash commands or `"prompt"` for LLM-based evaluation
  - `command`: (For `type: "command"`) The bash command to execute (can use `$CLAUDE_PROJECT_DIR` environment variable)
  - `prompt`: (For `type: "prompt"`) The prompt to send to the LLM for evaluation
  - `timeout`: (Optional) How long a hook should run, in seconds, before canceling that specific hook

For events like `UserPromptSubmit`, `Stop`, `SubagentStop`, and `Setup`
that don’t use matchers, you can omit the matcher field:

Copy

Ask AI

```
{
  "hooks": {
    "UserPromptSubmit": [\\
      {\\
        "hooks": [\\
          {\\
            "type": "command",\\
            "command": "/path/to/prompt-validator.py"\\
          }\\
        ]\\
      }\\
    ]
  }
}
```

### [​](https://code.claude.com/docs/en/hooks\\#project-specific-hook-scripts)  Project-Specific Hook Scripts

You can use the environment variable `CLAUDE_PROJECT_DIR` (only available when
Claude Code spawns the hook command) to reference scripts stored in your project,
ensuring they work regardless of Claude’s current directory:

Copy

Ask AI

```
{
  "hooks": {
    "PostToolUse": [\\
      {\\
        "matcher": "Write|Edit",\\
        "hooks": [\\
          {\\
            "type": "command",\\
            "command": "\\"$CLAUDE_PROJECT_DIR\\"/.claude/hooks/check-style.sh"\\
          }\\
        ]\\
      }\\
    ]
  }
}
```

### [​](https://code.claude.com/docs/en/hooks\\#plugin-hooks)  Plugin hooks

[Plugins](https://code.claude.com/docs/en/plugins) can provide hooks that integrate seamlessly with your user and project hooks. Plugin hooks are automatically merged with your configuration when plugins are enabled.**How plugin hooks work**:

- Plugin hooks are defined in the plugin’s `hooks/hooks.json` file or in a file given by a custom path to the `hooks` field.
- When a plugin is enabled, its hooks are merged with user and project hooks
- Multiple hooks from different sources can respond to the same event
- Plugin hooks use the `${CLAUDE_PLUGIN_ROOT}` environment variable to reference plugin files

**Example plugin hook configuration**:

Copy

Ask AI

```
{
  "description": "Automatic code formatting",
  "hooks": {
    "PostToolUse": [\\
      {\\
        "matcher": "Write|Edit",\\
        "hooks": [\\
          {\\
            "type": "command",\\
            "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh",\\
            "timeout": 30\\
          }\\
        ]\\
      }\\
    ]
  }
}
```

Plugin hooks use the same format as regular hooks with an optional `description` field to explain the hook’s purpose.

Plugin hooks run alongside your custom hooks. If multiple hooks match an event, they all execute in parallel.

**Environment variables for plugins**:

- `${CLAUDE_PLUGIN_ROOT}`: Absolute path to the plugin directory
- `${CLAUDE_PROJECT_DIR}`: Project root directory (same as for project hooks)
- All standard environment variables are available

See the [plugin components reference](https://code.claude.com/docs/en/plugins-reference#hooks) for details on creating plugin hooks.

### [​](https://code.claude.com/docs/en/hooks\\#hooks-in-skills-and-agents)  Hooks in skills and agents

In addition to settings files and plugins, hooks can be defined directly in [skills](https://code.claude.com/docs/en/skills) and [subagents](https://code.claude.com/docs/en/sub-agents) using frontmatter. These hooks are scoped to the component’s lifecycle and only run when that component is active.**Supported events**: `PreToolUse`, `PostToolUse`, and `Stop`**Example in a Skill**:

Copy

Ask AI

```
---
name: secure-operations
description: Perform operations with security checks
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/security-check.sh"
---
```

**Example in an agent**:

Copy

Ask AI

```
---
name: code-reviewer
description: Review code changes
hooks:
  PostToolUse:
    - matcher: "Edit|Write"
      hooks:
        - type: command
          command: "./scripts/run-linter.sh"
---
```

Component-scoped hooks follow the same configuration format as settings-based hooks but are automatically cleaned up when the component finishes executing.**Additional option for skills:**

- `once`: Set to `true` to run the hook only once per session. After the first successful execution, the hook is removed. Note: This option is currently only supported for skills, not for agents.

## [​](https://code.claude.com/docs/en/hooks\\#prompt-based-hooks)  Prompt-Based Hooks

In addition to bash command hooks (`type: "command"`), Claude Code supports prompt-based hooks (`type: "prompt"`) that use an LLM to evaluate whether to allow or block an action. Prompt-based hooks are currently only supported for `Stop` and `SubagentStop` hooks, where they enable intelligent, context-aware decisions.

### [​](https://code.claude.com/docs/en/hooks\\#how-prompt-based-hooks-work)  How prompt-based hooks work

Instead of executing a bash command, prompt-based hooks:

1. Send the hook input and your prompt to a fast LLM (Haiku)
2. The LLM responds with structured JSON containing a decision
3. Claude Code processes the decision automatically

### [​](https://code.claude.com/docs/en/hooks\\#configuration-2)  Configuration

Copy

Ask AI

```
{
  "hooks": {
    "Stop": [\\

---

Source: [Claudary](https://claudary.paisolsolutions.com/skills/claude-code-hooks-docs) · https://claudary.paisolsolutions.com
