John Lindquist's TypeScript Hooks for Claude Code
Table of content

John Lindquist co-founded egghead.io in 2013 and invented the bite-sized screencast format that taught millions of developers AngularJS, React, and TypeScript. After 16 years of teaching developers, he now works on AI developer experience at Vercel and has spent over 1 billion tokens using Claude Code.
His claude-hooks project solves a specific problem: Claude Code hooks are powerful but writing them in raw shell scripts means no autocomplete, no type checking, and constant trips to the documentation to remember payload structures.
Background
- Co-founded egghead.io in 2013, turning free AngularJS screencasts into a developer education platform
- Previously Technical Architect at Roundarch, building apps for the Air Force, HBO, and Bloomberg
- WebStorm evangelist at JetBrains before going full-time on egghead
- Created Script Kit, an automation tool with 4.2k GitHub stars
- Currently AI DX at Vercel
Type-Safe Hooks
The claude-hooks project gives you TypeScript definitions for all hook events. Instead of guessing what fields exist on a PreToolUse payload, you get IntelliSense:
npx claude-hooks
This scaffolds a .claude/hooks/ directory with typed payloads:
// .claude/hooks/index.ts
import { PreToolUse, PostToolUse, Notification, Stop } from './lib'
export async function preToolUse(payload: PreToolUse) {
// payload.tool_name, payload.tool_input fully typed
if (payload.tool_name === 'write_file') {
// Block writes to production files
if (payload.tool_input.path.includes('production')) {
return { action: 'block', reason: 'Cannot modify production files' }
}
}
}
export async function postToolUse(payload: PostToolUse) {
// Run formatters after file edits
if (payload.tool_name === 'write_file') {
await formatFile(payload.tool_input.path)
}
}
The type definitions cover all eight lifecycle events: UserPromptSubmit, PreToolUse, PostToolUse, Notification, Stop, and the session variants.
Hook Events
| Event | When It Fires | Use Case |
|---|---|---|
| UserPromptSubmit | Before Claude sees your prompt | Validate or enhance prompts |
| PreToolUse | Before any tool execution | Block dangerous operations |
| PostToolUse | After tool completion | Format code, run tests |
| Notification | When Claude sends notifications | Custom alerts (Slack, native) |
| Stop | When Claude finishes responding | Session cleanup, logging |
Beyond Hooks
John also created mdflow, a CLI that runs Markdown files as executable prompts against Claude, Codex, Gemini, or Copilot. Write your prompt once in .md, run it against any backend:
mdflow run prompt.md --backend claude
mdflow run prompt.md --backend codex
His Claude Code Power-User workshop has trained 333 developers across seven cohorts, covering hooks, the SDK, sub-agents, and MCP integrations.
Key Takeaways
| Principle | Implementation |
|---|---|
| Type everything | Use claude-hooks for typed payloads instead of raw JSON |
| Automate formatting | PostToolUse hooks run prettier/eslint after every edit |
| Block mistakes early | PreToolUse hooks prevent writes to sensitive paths |
| Learn from volume | 1 billion tokens reveals patterns you miss in casual use |
Links
- claude-hooks - TypeScript hook system
- Script Kit - Desktop automation
- mdflow - Multi-backend prompt runner
- Claude Code Workshop - Live training
- egghead.io - Developer education platform
Next: Boris Cherny’s Claude Code
Get updates
New guides, workflows, and AI patterns. No spam.
Thank you! You're on the list.