Skip to content
Back to skills

Pre Post Hooks

ASecurity

Guide for configuring PreToolUse, PostToolUse, and Stop hooks in Claude Code. Use when the user asks about hooks, wants to run commands before/after tool calls, needs auto-formatting, auto-linting, validation gates, or mentions settings.json hook config.

  • 4 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aitypescriptshellbashrailsgit

Works with

  • claude code

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add VersoXBT/claude-initial-setup --skill pre-post-hooks --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Pre Post Hooks?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Pre Post Hooks
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/versoxbt-pre-post-hooks/badge)](https://www.skillsdirectory.com/skills/versoxbt-pre-post-hooks)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: pre-post-hooks
description: >
  Guide for configuring PreToolUse, PostToolUse, and Stop hooks in Claude Code.
  Use when the user asks about hooks, wants to run commands before/after tool calls,
  needs auto-formatting, auto-linting, validation gates, or mentions settings.json hook config.
---

# Pre/Post Hooks

Claude Code hooks are shell commands that execute automatically in response to tool events. They enable validation, formatting, and guardrails without manual intervention.

## When to Use
- User wants to run a command before or after a tool executes
- User asks about PreToolUse, PostToolUse, or Stop hooks
- User wants to add validation gates or blockers
- User needs to configure hooks in settings.json
- User mentions auto-running commands on file edit, git push, or session end

## Core Patterns

### Hook Types and Lifecycle

```
PreToolUse  --> Tool Executes --> PostToolUse
                                       |
                                  (session ends)
                                       |
                                     Stop
```

- **PreToolUse**: Runs before a tool call. Can block execution by returning a non-zero exit code.
- **PostToolUse**: Runs after a tool call completes. Used for side effects like formatting or checks.
- **Stop**: Runs when the agent session ends. Used for final audits or cleanup.

### Hook Configuration in settings.json

Hooks live in `~/.claude/settings.json` under the `hooks` key:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "command": "echo 'About to write a file'",
        "description": "Log before file writes"
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit",
        "command": "npx prettier --write \"$CLAUDE_FILE_PATH\"",
        "description": "Auto-format after editing JS/TS files"
      }
    ],
    "Stop": [
      {
        "command": "echo 'Session ended'",
        "description": "Log session end"
      }
    ]
  }
}
```

### Matcher Patterns

The `matcher` field filters which tool triggers the hook. It matches against tool names:

```json
{
  "matcher": "Edit",
  "command": "..."
}
```

Common tool names to match:
- `Write` — file creation
- `Edit` — file modification
- `Bash` — shell command execution
- `Read` — file reading
- `Glob` — file search
- `Grep` — content search

Use pipe `|` for multiple matchers:

```json
{
  "matcher": "Write|Edit",
  "command": "npx prettier --write \"$CLAUDE_FILE_PATH\""
}
```

Omit `matcher` entirely to match ALL tool calls (useful for Stop hooks).

### Environment Variables in Hooks

Hooks receive context via environment variables:

| Variable | Description |
|----------|-------------|
| `CLAUDE_FILE_PATH` | The file path being operated on |
| `CLAUDE_TOOL_NAME` | Name of the tool being called |
| `CLAUDE_SESSION_ID` | Current session identifier |

### Blocking with PreToolUse

A PreToolUse hook that exits non-zero blocks the tool from executing:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "command": "echo \"$CLAUDE_FILE_PATH\" | grep -qv '\\.md$' || (echo 'BLOCKED: Do not create markdown files' && exit 1)",
        "description": "Block creation of .md files"
      }
    ]
  }
}
```

### PostToolUse Side Effects

Run checks or formatting after tool execution without blocking:

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit",
        "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -q '\\.ts$'; then npx tsc --noEmit \"$CLAUDE_FILE_PATH\" 2>&1 | head -20; fi",
        "description": "Type-check TypeScript files after edit"
      }
    ]
  }
}
```

### Stop Hook for Final Audit

```json
{
  "hooks": {
    "Stop": [
      {
        "command": "git diff --cached --name-only | xargs grep -l 'console.log' 2>/dev/null && echo 'WARNING: console.log found in staged files'",
        "description": "Audit staged files for console.log before session ends"
      }
    ]
  }
}
```

## Anti-Patterns

- **Slow hooks on hot paths**: Do not run expensive commands (full test suite, large builds) in PostToolUse on every Edit. It blocks the agent loop. Use targeted, fast checks instead.
- **Blocking reads**: Do not use PreToolUse to block Read or Grep calls. These are non-destructive and blocking them disrupts exploration.
- **Missing error handling**: Hook commands that fail silently hide problems. Always include meaningful error messages in blocking hooks.
- **Hardcoded paths**: Use `$CLAUDE_FILE_PATH` instead of hardcoding file paths. Hooks should be project-agnostic.
- **Too many hooks**: Each hook adds latency to every matching tool call. Keep the hook list focused on high-value checks.

## Quick Reference

| Hook Type | Timing | Can Block? | Use Case |
|-----------|--------|------------|----------|
| PreToolUse | Before tool | Yes (exit 1) | Validation, gates, warnings |
| PostToolUse | After tool | No | Formatting, type-checking, linting |
| Stop | Session end | No | Final audits, cleanup |

**Config location**: `~/.claude/settings.json` > `hooks`
**Matcher syntax**: Tool name string, pipe-separated for multiple
**Blocking**: Only PreToolUse can block (non-zero exit code)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.