🎯 What Are Function Hooks
Anthropic released function hooks — which Ray calls "the best feature in Claude Code yet." They take the existing shell-hooks system to the next level, making Claude Code far more hackable and customizable, while solving the core problems with hooks. 0:00
🔒 The Limits of Old Hooks
Existing shell hooks were useful but couldn't do six things. Function hooks solve all six. 1:49
| Capability | Shell hooks | Function hooks |
|---|---|---|
| Rewrite the prompt / input | ❌ | ✅ |
| Append context (e.g. company knowledge base) | ❌ | ✅ |
| Draw UI (buttons, status rows) | ❌ | ✅ |
| Ask user questions | ❌ | ✅ |
| Add tools / edit tool descriptions | ❌ | ✅ |
| Memory across hooks & sessions | ❌ | ✅ |
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude. This unlocks the built-in /plugin-authoring skill ("write or debug a Claude Code plugin made of function hooks").🧩 The Express.js Analogy
Ray's mental model: function hooks are Express.js middleware for Claude Code. On any tool call, you match against a tool and optionally a regex, then block, rewrite, or short-circuit. 2:17
| Express.js | Function hooks |
|---|---|
Block requests missing an auth header, else next() | On any tool call, match the Bash tool; if it matches a destructive regex, block it |
| Middleware can rewrite the request | Rewrite input — e.g. replace npm with pnpm install to prevent accidental npm use |
| Middleware can short-circuit with a cached response | Web fetch: check the store first, return the cached copy if the URL was already fetched |
🤐 Example 1: The Secret Redactor
The security killer-app: intercept secrets before they ever enter the session transcript. 5:00
transcript_redactor.json + redact.ts) that:
- Measures entropy to detect secrets, plus regex for emails and IPs
- Redacts the secret as soon as you hit enter — replaces it with an ID
- Stores the secret in-memory, so Claude uses the ID, never the secret
- Rewrites it back to the real secret only at request time
🖥️ Example 2: Vercel Deploy UI
Function hooks can draw custom UI rows in Claude Code — the feature Ray is most excited about. 7:54
queued → building → ready) and elapsed time in a status row next to the prompt, with a hide/show button. Each plugin gets a live data panel. He triggers a deploy → watches the row tick through stages → "ready, 5m 50s."/plugin-authoring → describe the hook → tell it to "interview me, give me prototypes to play with before coding" → it asks clarifying questions → builds it.🔧 More Hook Patterns
The rest of the video is a rapid-fire catalog of patterns — the "hundreds of examples" Ray says are now possible. 11:29
| Pattern | What it does |
|---|---|
| Dry runs | Block real commands until a dry-run has run first — combined with a big red "you're in production / dry mode" UI row |
| Refactor gate | Every time an edited file exceeds 1,000 lines, ask "refactor into smaller files?" (models still love 2,000–3,000-line files) |
| Speak on turn end | Pass a summary to a Haiku model ($model), then speak it via built-in TTS |
| Audit trail | Send every event to your own log store — compliance for healthcare/payments |
| Newsletter guard | Block sending an email until the ask tool confirms you actually want it sent |
| Knowledge-base injection | Generate keywords from the prompt, query your company KB via $http, inject context into the session |
| PR quiz | Before opening a PR, Claude generates a quiz to confirm you understand the changes |
| Time guard | If a turn exceeds 10 minutes, save the result to a separate file so nothing is lost |
🔗 Shell Hooks Explained (Ray's blog) · Anthropic's official announcement (X)
💡 Key Takeaways
- Function hooks are deterministic control — rules in CLAUDE.md fade; hooks enforce mechanically, every time.
- They're Express.js middleware — block, rewrite, or short-circuit any tool call by matching tool + regex.
- They solve all six limits of shell hooks — rewrite, append context, draw UI, ask questions, add tools, and memory.
- Secrets never hit the transcript — the redactor swaps secrets for IDs and stores them in-memory, swapping back only at request time.
- You can override built-in tools — intercept web search to use Exa behind the scenes, no MCP server needed.
- Custom UI rows — live deploy status, dry-run warnings, per-plugin data panels with hide/show buttons.
- The ask + memory primitives — gate destructive actions behind a user question, and persist state across turns and sessions.
- Migrate CLAUDE.md → hooks.json — and share them as plugins via a shared GitHub repo for the whole team.