15 copy-paste hook recipes for Claude Code — security, quality, git, and workflow automation
Hooks let you run shell commands before or after Claude Code uses a tool. They're configured in ~/.claude/settings.json and fire automatically — no manual intervention.
This repo gives you 15 battle-tested hook recipes organized by category, plus a CLI to install them in seconds.
┌─────────────────────────────────────────────────┐
│ Claude Code │
│ │
│ User prompt → Tool call → Hook fires → Result │
│ ↑ │
│ PreToolUse │
│ PostToolUse │
│ │
│ hooks/ │
│ ├── security/ Block secrets, force-push, rm │
│ ├── quality/ Auto-lint, format, test, types │
│ ├── git/ Conventional commits, branches │
│ └── workflow/ Logging, backup, notifications │
└─────────────────────────────────────────────────┘
Install a single hook:
npx claude-hooks-kit install secret-scannerInstall an entire category:
npx claude-hooks-kit install securityList all available hooks:
npx claude-hooks-kit listPreview before installing:
npx claude-hooks-kit show auto-lint| Hook | What it does |
|---|---|
secret-scanner |
Scans staged files for API keys, tokens, and passwords before commit |
no-env-commit |
Blocks staging .env, .pem, .key, and credential files |
no-force-push |
Prevents git push --force to main/master |
no-destructive-commands |
Blocks rm -rf /, DROP TABLE, git reset --hard, etc. |
| Hook | What it does |
|---|---|
auto-lint |
Runs ESLint/Ruff after JS/TS/Python file edits |
auto-format |
Runs Prettier on files after edits |
test-on-change |
Finds and runs related test files when source changes |
type-check |
Runs tsc --noEmit after TypeScript file edits |
| Hook | What it does |
|---|---|
conventional-commits |
Enforces feat:, fix:, refactor: commit format |
branch-protection |
Blocks direct commits to main/master |
no-wip-push |
Prevents pushing WIP/fixup/squash commits |
co-author |
Auto-appends Co-Authored-By trailer to commits |
| Hook | What it does |
|---|---|
session-logger |
Logs all tool calls to ~/.claude/logs/YYYY-MM-DD.log |
notify-on-error |
macOS notification when a command fails |
auto-gitignore |
Auto-adds .env files to .gitignore when created |
backup-before-edit |
Creates file backup before Claude edits |
Don't want the CLI? Copy any hook directly into your ~/.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "if echo \"$TOOL_INPUT\" | grep -qE 'git push.*(--force|-f)'; then if echo \"$TOOL_INPUT\" | grep -qE '(main|master)'; then echo 'BLOCKED: Force-push to main/master is not allowed.' >&2; exit 2; fi; fi; exit 0"
}
]
}
}PreToolUse PostToolUse
│ │
▼ ▼
exit 0 → allow tool exit 0 → continue
exit 2 → BLOCK tool (with msg) exit 0 → always continue
exit 1 → error (ask user) (post hooks can't block)
Available environment variables in hooks:
| Variable | Description |
|---|---|
$TOOL_NAME |
Name of the tool being called |
$TOOL_INPUT |
JSON input to the tool |
$TOOL_EXIT_CODE |
Exit code (PostToolUse only) |
Hooks stack. Install multiple hooks and they all fire in order:
npx claude-hooks-kit install security # all 4 security hooks
npx claude-hooks-kit install conventional-commits
npx claude-hooks-kit install auto-lintCheck what's installed:
npx claude-hooks-kit installedCreate a JSON file in the same format:
{
"description": "What this hook does",
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|Write|Edit",
"command": "your-shell-command-here; exit 0"
}
]
}
}Tips:
matcheris a regex against tool names:Bash,Write,Edit,Read,Glob,Grep- Use
exit 0to allow,exit 2to block (PreToolUse only) - Keep commands fast — they run on every matching tool call
- Test with
claude-hooks show <name>before installing
- claude-enchant — Auto-triggering behavioral rules for Claude Code
- awesome-claude-md — Curated CLAUDE.md examples + generator
- Claude Code Hooks Docs
MIT
Built by Anuar AX