Claude-initial-setup hook-recipes
install
source · Clone the upstream repo
git clone https://github.com/VersoXBT/claude-initial-setup
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/VersoXBT/claude-initial-setup "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/hooks/hook-recipes" ~/.claude/skills/versoxbt-claude-initial-setup-hook-recipes && rm -rf "$T"
manifest:
skills/hooks/hook-recipes/SKILL.mdsource content
Hook Recipes
A collection of battle-tested hook configurations for Claude Code. Copy these directly into
~/.claude/settings.json under the hooks key.
When to Use
- User asks for a specific hook recipe or example
- User wants to auto-format code after edits
- User wants to block certain file types from being created
- User wants warnings about console.log, TODO, or debug statements
- User needs a git push review gate
- User asks "how do I set up hooks for X"
Core Recipes
Recipe 1: Prettier Auto-Format on Edit
Formats JavaScript, TypeScript, CSS, and JSON files after every edit or write:
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(js|ts|jsx|tsx|css|scss|json|md)$'; then npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null; fi", "description": "Prettier auto-format" } ] } }
Recipe 2: TypeScript Type-Check After Edit
Runs
tsc --noEmit after editing TypeScript files to catch type errors immediately:
{ "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.tsx?$'; then npx tsc --noEmit --pretty 2>&1 | tail -20; fi", "description": "TypeScript type-check" }
Recipe 3: Console.log Warning
Warns when a file containing
console.log is edited. Does not block, just informs:
{ "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(js|ts|jsx|tsx)$'; then MATCHES=$(grep -n 'console\\.log' \"$CLAUDE_FILE_PATH\" 2>/dev/null); if [ -n \"$MATCHES\" ]; then echo \"WARNING: console.log found in $CLAUDE_FILE_PATH:\"; echo \"$MATCHES\" | head -5; fi; fi", "description": "Warn about console.log in edited files" }
Recipe 4: Git Push Review Gate
Opens the diff for review before allowing a git push. Blocks the push so the user can inspect:
{ "hooks": { "PreToolUse": [ { "matcher": "Bash", "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'git push'; then echo '=== FILES TO BE PUSHED ===' && git diff --stat HEAD~1 && echo '' && echo 'Review the above changes. This hook will allow the push to proceed.'; fi", "description": "Show diff summary before git push" } ] } }
To actually block and require confirmation:
{ "matcher": "Bash", "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'git push'; then echo 'BLOCKED: Git push requires explicit user approval.' && exit 1; fi", "description": "Block git push (user must approve)" }
Recipe 5: Doc File Blocker
Prevents creation of unnecessary documentation files (.md, .txt) unless in a docs directory:
{ "hooks": { "PreToolUse": [ { "matcher": "Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(md|txt)$' && ! echo \"$CLAUDE_FILE_PATH\" | grep -q '/docs/'; then echo 'BLOCKED: Do not create .md or .txt files outside /docs/' && exit 1; fi", "description": "Block markdown/text file creation outside docs/" } ] } }
Recipe 6: ESLint Auto-Fix
Auto-fix lint issues and report remaining problems:
{ "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(js|ts|jsx|tsx)$'; then npx eslint --fix --no-warn-ignored \"$CLAUDE_FILE_PATH\" 2>&1 | head -20; fi", "description": "ESLint auto-fix after edit" }
Recipe 7: Secret Leak Prevention
Block file writes that contain potential secrets:
{ "hooks": { "PreToolUse": [ { "matcher": "Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(env|key|pem|credentials)$'; then echo 'BLOCKED: Cannot write secret/credential files' && exit 1; fi", "description": "Block writing secret files" } ] } }
Recipe 8: Session-End Audit
Check all modified files for debug artifacts before the session ends:
{ "hooks": { "Stop": [ { "command": "MODIFIED=$(git diff --name-only 2>/dev/null); if [ -n \"$MODIFIED\" ]; then echo '=== Session End Audit ===' && echo \"$MODIFIED\" | xargs grep -ln 'console\\.log\\|debugger\\|TODO.*HACK\\|FIXME' 2>/dev/null | while read f; do echo \"WARNING: Debug artifact in $f\"; done; fi", "description": "Audit modified files for debug artifacts at session end" } ] } }
Recipe 9: Test Runner After Source Edit
Run the related test file whenever a source file is modified:
{ "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.ts$' && ! echo \"$CLAUDE_FILE_PATH\" | grep -q '\\.test\\.'; then TEST=$(echo \"$CLAUDE_FILE_PATH\" | sed 's/\\.ts$/.test.ts/'); if [ -f \"$TEST\" ]; then npx vitest run \"$TEST\" --reporter=dot 2>&1 | tail -10; fi; fi", "description": "Run related test file after source edit" }
Combining Recipes
A complete settings.json with multiple hooks:
{ "hooks": { "PreToolUse": [ { "matcher": "Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(md|txt)$' && ! echo \"$CLAUDE_FILE_PATH\" | grep -q '/docs/'; then echo 'BLOCKED: No docs outside /docs/' && exit 1; fi", "description": "Doc blocker" }, { "matcher": "Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(env|key|pem)$'; then echo 'BLOCKED: Secret file' && exit 1; fi", "description": "Secret blocker" } ], "PostToolUse": [ { "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(ts|tsx)$'; then npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null; fi", "description": "Prettier" }, { "matcher": "Edit|Write", "command": "if echo \"$CLAUDE_FILE_PATH\" | grep -qE '\\.(ts|tsx)$'; then npx tsc --noEmit --pretty 2>&1 | tail -15; fi", "description": "TSC check" } ], "Stop": [ { "command": "git diff --name-only 2>/dev/null | xargs grep -ln 'console\\.log' 2>/dev/null && echo 'WARNING: console.log in modified files'", "description": "Console.log audit" } ] } }
Anti-Patterns
- Stacking too many PostToolUse hooks: Each hook runs sequentially. Five hooks at 2 seconds each means 10 seconds of delay after every edit. Prioritize the most valuable checks.
- Blocking reads or greps: Never use PreToolUse to block non-destructive tools like Read, Grep, or Glob. These are essential for exploration.
- Missing file extension filters: A hook without
runs on every file type, including binaries and images. Always filter by extension.grep -qE '\\.ts$' - Swallowing errors silently: Redirect stderr to
only for known noise. Important errors should surface to the agent./dev/null - Using interactive commands: Hooks cannot prompt for input. Commands like
orgit add -i
will hang.read -p
Quick Reference
| Recipe | Type | Blocks? | Target Files |
|---|---|---|---|
| Prettier | PostToolUse | No | .js/.ts/.css/.json |
| TSC check | PostToolUse | No | .ts/.tsx |
| Console.log warn | PostToolUse | No | .js/.ts/.jsx/.tsx |
| Git push review | PreToolUse | Optional | Bash (git push) |
| Doc blocker | PreToolUse | Yes | .md/.txt |
| Secret blocker | PreToolUse | Yes | .env/.key/.pem |
| ESLint fix | PostToolUse | No | .js/.ts/.jsx/.tsx |
| Session audit | Stop | No | All modified files |
| Test runner | PostToolUse | No | .ts (non-test) |