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