A

Advanced Hook Development

Boost productivity using this skill, should, used, user. Includes structured workflows, validation checks, and reusable patterns for development.

SkillClipticsdevelopmentv1.0.0MIT
0 views0 copies

Hook Development for Claude Code

A Claude Code skill for building event-driven automation hooks — scripts that execute in response to Claude Code events like tool calls, file changes, and code generation, enabling validation, logging, and custom workflows.

When to Use This Skill

Choose this skill when:

  • Automating validation before file writes or commits
  • Logging Claude Code actions for auditing or analytics
  • Enforcing project-specific rules (no secrets, file naming, etc.)
  • Running formatters or linters automatically after code generation
  • Building custom integrations triggered by Claude Code events
  • Adding pre/post hooks for any Claude Code tool execution

Consider alternatives when:

  • You need git hooks specifically (use git hooks directly)
  • You need CI/CD automation (use GitHub Actions)
  • You need IDE-specific extensions (use VS Code extension API)

Quick Start

# Configure hooks in your settings claude settings
// .claude/settings.json { "hooks": { "PreToolUse": [ { "matcher": "Write|Edit", "command": "node .claude/hooks/validate-write.js $FILE_PATH" } ], "PostToolUse": [ { "matcher": "Write|Edit", "command": "npx prettier --write $FILE_PATH" } ], "Notification": [ { "matcher": ".*", "command": "node .claude/hooks/log-action.js" } ] } }

Core Concepts

Hook Event Types

EventFires WhenCommon Use
PreToolUseBefore a tool executesValidate inputs, block operations
PostToolUseAfter a tool completesFormat code, run checks
NotificationOn any notable actionLogging, analytics
StopSession endsCleanup, summary generation

Hook Script Examples

// .claude/hooks/validate-write.js // Block writes to protected files const protectedFiles = ['.env', 'package-lock.json', 'credentials.json']; const filePath = process.argv[2]; if (protectedFiles.some(f => filePath.endsWith(f))) { console.error(`BLOCKED: Cannot modify protected file: ${filePath}`); process.exit(1); // Non-zero exit blocks the operation } process.exit(0); // Zero exit allows the operation
// .claude/hooks/auto-format.js // Auto-format files after write const { execSync } = require('child_process'); const filePath = process.argv[2]; if (filePath.match(/\.(ts|tsx|js|jsx)$/)) { execSync(`npx prettier --write "${filePath}"`, { stdio: 'inherit' }); } if (filePath.match(/\.(py)$/)) { execSync(`black "${filePath}"`, { stdio: 'inherit' }); }
// .claude/hooks/no-secrets.js // Scan for secrets before allowing writes const fs = require('fs'); const filePath = process.argv[2]; const content = fs.readFileSync(filePath, 'utf-8'); const secretPatterns = [ /sk[-_]live[-_][a-zA-Z0-9]{20,}/, // Stripe live keys /AKIA[0-9A-Z]{16}/, // AWS access keys /ghp_[a-zA-Z0-9]{36}/, // GitHub personal tokens /-----BEGIN (RSA )?PRIVATE KEY-----/, // Private keys ]; for (const pattern of secretPatterns) { if (pattern.test(content)) { console.error(`BLOCKED: Potential secret detected in ${filePath}`); process.exit(1); } }

Configuration

ParameterTypeDefaultDescription
matcherstring".*"Regex pattern matching tool names to hook
commandstringShell command to execute (required)
timeoutnumber10000Maximum execution time in milliseconds
cwdstring"."Working directory for the hook command
envobject{}Additional environment variables

Available Environment Variables

VariableDescription
$TOOL_NAMEName of the tool being executed
$FILE_PATHFile path being read/written (if applicable)
$SESSION_IDCurrent Claude Code session identifier
$PROJECT_DIRRoot directory of the project

Best Practices

  1. Keep hooks fast (under 2 seconds) — hooks run synchronously and block Claude Code execution; slow hooks degrade the interactive experience. Move heavy processing to background jobs.

  2. Use non-zero exit codes to block operations — return exit(1) from PreToolUse hooks to prevent the operation; return exit(0) to allow it. Use stderr for error messages.

  3. Match specific tools, not everything — use precise matchers like Write|Edit instead of .* to avoid running hooks on irrelevant operations.

  4. Test hooks in isolation before configuring — run the hook script manually with test inputs before adding it to settings; a broken hook can block all Claude Code operations.

  5. Log actions to a file for debugging — PostToolUse hooks that append to a .claude/hooks.log file make it easy to review what happened during a session.

Common Issues

Hook blocks all operations unexpectedly — A bug in the hook script causes non-zero exit on valid operations. Test with specific file paths and tool names. Add error handling so the hook fails gracefully.

Hook runs on wrong tool calls — The matcher regex is too broad. Use ^Write$ to match only the Write tool, not Write which would also match NotebookWrite or TodoWrite.

Hooks don't run in VS Code extension — Hooks configured in CLI settings may not apply in the VS Code extension. Verify the settings file location and ensure hooks are configured at the project level (.claude/settings.json).

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates