Lesson
Type-Safe Claude Code Hooks with Bun and TypeScript
Parse hook JSON with Bun, add TypeScript types from the SDK, and build maintainable automation that beats shell scripts.
- Access
- Included
- Transcript
- Needs source
Type-safe hooks turn Claude Code's JSON payloads into structured TypeScript. Use Bun to parse stdin, the official SDK for types, and skip the jq gymnastics.
The shell hook problem
Basic hooks work but lack structure:
- JSON parsing needs extra tools
- No autocompletion or type checking
- Complex logic gets messy fast
Bun + TypeScript solution
Set up a typed hook environment:
mkdir .claude/hooks && cd .claude/hooks
bun init
bun i @anthropic-ai/claude-code
Write the hook
Create .claude/hooks/UserPromptSubmit.ts:
import { type UserPromptSubmitHookInput } from "@anthropic-ai/claude-code";
const input = await Bun.stdin.json() as UserPromptSubmitHookInput;
const { cwd, prompt } = input;
// Example: log hook data
await Bun.write(
".claude/hooks/last-prompt.json",
JSON.stringify({ prompt, cwd }, null, 2)
);
Connect it
Update .claude/settings.local.json:
{
"hooks": {
"UserPromptSubmit": [{
"matcher": "*",
"hooks": [{
"type": "command",
"command": "bun run .claude/hooks/UserPromptSubmit.ts"
}]
}]
}
}
Test:
claude
hello world
Why this pattern scales
- Type safety: SDK types catch errors at write-time
- One-line parsing:
Bun.stdin.json()replaces complex pipes - NPM ecosystem: Use any package for advanced automation