Claude Code Hooks Starter (Free)

Six Claude Code hooks you can copy today, and a tester that shows exactly what Claude Code will do with your hook's output before you wire it up.

Claude Code Hooks Starter (Free) cover

The 6 examples

Six small, working Claude Code hooks, one for each event people ask about, plus hooktest, a local tester that runs any hook script (Python, Bash, Node, anything) with a sample event and tells you what Claude Code would do with its output.

HookEventWhat it shows you how to do
session_context.pySessionStartGive Claude the git branch and uncommitted files at the start of every session (additionalContext).
prompt_guard.pyUserPromptSubmitBlock a prompt that contains an API key (decision: "block"); otherwise add today's date as context.
block_dangerous.pyPreToolUse (Bash)Deny rm -rf / / ~ and force-push to main/master (permissionDecision: "deny").
format_on_edit.pyPostToolUse (Edit|Write|MultiEdit)Run ruff / prettier / gofmt / rustfmt on the file Claude just edited; exit 2 on failure so Claude sees the error.
notify.pyNotificationDesktop notification when Claude needs you, through terminalSequence (no /dev/tty).
stop_run_tests.pyStopRun your tests before Claude finishes; if they fail, keep it working (decision: "block"), with a stop_hook_active guard so it can't loop.

Python 3.9+ standard library only. No network. Free to use and change (see LICENSE.txt).

What you get

The screenshot is real output from the kit’s own commands. Tested from a fresh download of this exact zip: ./run_tests.sh ran 11 tests OK on Python 3.13 and 3.10.

Real terminal output from Claude Code Hooks Starter: demo and passing tests

Try it (no Claude Code needed)

./tools/demo.sh          # runs every hook against a sample event
./run_tests.sh           # 11 test groups

# test YOUR hook, in any language
python3 tools/hooktest.py path/to/your-hook.sh samples/pre_tool_use_bash.json
python3 tools/hooktest.py hooks/block_dangerous.py --event PreToolUse --tool Bash --command "git push -f origin main"
python3 tools/hooktest.py hooks/stop_run_tests.py samples/stop.json --json

hooktest reports the exit code, whether stdout is JSON / plain text / broken JSON, the outcome in plain words (BLOCKS, DENIES, ASKS, adds context, keeps working, non-blocking error) and PROBLEM lines for the usual mistakes: wrong hookEventName, permissionDecision values that don't exist, top-level decision on PreToolUse, decision: "block" without a reason, JSON with a non-zero exit, output over the 10,000-character cap. It exits 1 if there are problems, so you can run it in CI.

Install

As a plugin: enable this folder as a Claude Code plugin; hooks/hooks.json uses ${CLAUDE_PLUGIN_ROOT}.

In one project: copy hooks/ to .claude/hooks/ and merge settings.example.json into .claude/settings.json. Delete the hooks you don't want. Run /hooks in Claude Code to check they're listed.

Settings for the examples (environment variables):

  • HOOK_TEST_CMD="npm test" turns on the Stop hook (off when unset). HOOK_TEST_TIMEOUT (seconds, default 300).
  • HOOK_FORMAT_CMD="ruff format" forces one formatter; otherwise it picks by file extension and skips formatters that aren't installed.
  • HOOK_NOTIFY_OSC=9 for iTerm2 / Windows Terminal / WezTerm (default OSC 777: Ghostty, Warp, urxvt).

Rules these examples follow (from the Claude Code hooks reference)

  • Input arrives as JSON on stdin. Print one JSON object to stdout, or nothing.
  • Exit 0 = success, fields apply. Exit 2 = block (PreToolUse, UserPromptSubmit, Stop...) or show stderr to Claude (PostToolUse). Any other exit = non-blocking error: the action goes ahead.
  • A PreToolUse hook that prints nothing doesn't approve anything; normal permissions apply.
  • Use exec form ("command": "python3", "args": ["${CLAUDE_PLUGIN_ROOT}/hooks/x.py"]) so paths with spaces work.
  • A hook that can't start doesn't block unless you set "onFailure": "block" (Claude Code v2.1.295+).

Honest limits

Examples, not a security product. The key patterns catch common formats only. The Stop hook runs your test command with your permissions.

Format and license

Zip, 18 KB, v1.0.1, 21 files, plugin youraitools-hooks-starter. Free to use, modify and share for any purpose, including commercial work, as long as this notice stays in copies. Not affiliated with or endorsed by Anthropic.

FAQ

Is it really free?
Yes, free download, use it in any project.
Does hooktest need Claude Code?
No, it runs your hook script directly with a sample event.
Does it work with Bash or Node hooks?
Yes, hooktest runs any executable.
How do I get the files?
Click Download free. The zip downloads straight away: no checkout, no account.
Do I have to sign up for the newsletter?
No. The form is optional and the download works without it.

Get Claude Code Hooks Starter (Free)

Free Claude Code hooks examples: SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, Notification and Stop, plus a local tester that checks your hook's output.

Pairs well with

Download$12

Cursor Rules Pack

24 Cursor rules (.mdc) for Next.js, TypeScript, React, Python, FastAPI, Django, Go, Rust and more. Detects your stack, installs in one command, lints your rules. $12 once.

View Cursor Rules Pack
DownloadFree

Cursor Rules Starter (Free)

Free Cursor rules examples in .mdc format: agent workflow, commits, testing, security, code review. Includes a linter that shows why a rule isn't applying.

View Cursor Rules Starter (Free)
DownloadFree

CLAUDE.md Linter (Free)

Free CLAUDE.md linter: broken @imports, files over 200 lines, .claude/rules paths that match nothing, AGENTS.md conflicts, dead npm scripts, leaked keys. Offline, CI-ready.

View CLAUDE.md Linter (Free)

Related