Follow Discord
Sweep 06 Nov 2026 · 01:32Z Build v2.1.319 537 read Stable v2.1.311 Latest v2.1.318 Next v2.1.319 Feeds RSS JSON llms.txt llms-full.txt Unofficial
Mods

Building mods.

A mod is a plugin with a hooks module. You write one async function per event, and each one wraps the ones below it. Claude Code ships the runtime and writes type declarations for it, but documents almost none of it. This guide covers what's there, what it costs you, and where it behaves differently from what the types suggest.

Up to date for Claude Code 2.1.286. I read everything here out of the declarations Claude Code writes about itself, then ran it. When a page says something behaves a certain way, the command that showed it is on the page.

Pages10start at the top
The short versionone async function per eventregistered hooks wrap each other, earliest outermost
Read against2.1.286checked on Linux
Length224,049characters across the 10 pages

If you haven't written a mod before, read these in order. The first three explain how the whole thing works and everything else builds on them. After that, jump to whatever you need.

/
10 pages
  1. The model: read these first
  2. 01
    What a mod is

    What a mod is, which builds load one, what changes on Bedrock and Vertex, and a mod you can run in four files.

    22,923characters
    9 sections
    • On by default since 2.1.287
    • Bedrock, Vertex and other providers
    • It changes without notice
    • Claude Code's own features are mods
    • The fold
    • Where the code runs
    • These aren't the settings hooks
    • The smallest mod that does something
    • What's here and what isn't
  3. 02
    Anatomy of a mod

    plugin.json, hooks.json and register(), and what each of them is allowed to say.

    19,280characters
    11 sections
    • The two manifests
    • register, and the argument nobody uses
    • The import line
    • A mod is a closure
    • Registering an event twice
    • Three ways to name an event
    • Matchers
    • The loader reads your source, and it's strict
    • Getting $ out of a hook without breaking the rules
    • Check it before you run it
    • Running it
  4. 03
    Tiers, order and next()

    The five tiers, how a hook wraps the ones below it, and everything a hook can do with next().

    26,476characters
    12 sections
    • The five tiers
    • next
    • The two axioms
    • next.to
    • next.origin
    • next.trace
    • next.signal and next.budget
    • What failure actually does
    • .catch
    • Serial, and why
    • Streaming
    • Recursion
  5. Out of order, once you have the model
  6. 04
    The engine interface

    Every noun and verb on $, what's new since 2.1.283, and the calls with surprises in them.

    25,806characters
    12 sections
    • Every verb is also an event
    • The nouns
    • What's new since 2.1.283
    • What arrived between 2.1.272 and 2.1.283
    • $.plugin isn't a capability
    • $.telemetry is for the built-ins
    • The ops with surprises in them
    • $ outlives its dispatch
    • engine.create builds your $
    • Telling TypeScript about a new noun
    • A missing noun throws
    • The names moved once already
  7. 05
    The event catalogue

    Every event you can hook, what each one carries, and how a matcher narrows it.

    21,129characters
    7 sections
    • Engine events
    • Operation events
    • classic.\*
    • Globs
    • Events you can ask to rerun
    • What still has no event
    • Why use hooks at all
  8. 06
    Drawing on the screen

    Panes, components, elements per surface, and how to redraw without making the terminal flicker.

    18,168characters
    9 sections
    • ui.render
    • $.ui.resolve
    • The fifteen components
    • Elements, and the one that quietly draws nothing
    • Opening a pane
    • Interaction
    • Client modules
    • Redrawing
    • The smaller screen verbs
  9. 07
    userConfig and options

    Declaring options in plugin.json, what register() gets, and the three ways a config stops your mod loading.

    11,589characters
    6 sections
    • Declaring the fields
    • Three ways this goes wrong
    • Configuring one
    • What arrives at runtime
    • $.config is the /config menu
    • Reading the person's actual settings
  10. 08
    Testing a mod

    The built-in test kit: describe, expect, mock, test and tier, plus drawing your UI in a test.

    22,769characters
    12 sections
    • The five exports
    • tier, once, at the top
    • A test
    • Other plugins in the chain
    • Things about the test's $
    • Testing what you draw
    • mock
    • Matchers
    • What the kit doesn't have
    • Types in your editor
    • Validate first
    • What I haven't checked
  11. 09
    Confirmed gotchas

    Things that cost me an hour each, all reproduced on a real build, with the output that proves it.

    36,400characters
    11 sections
    • 1. A hook that fails doesn't block. It disappears.
    • 2. A good deny reason can make the model go around you
    • 3. A tool.call hook breaks worktree isolation for subagents
    • 4. $.session.usage() is mostly empty until the first turn completes
    • 5. The manifest validator doesn't type-check your defaults
    • 6. An unconfigured option reads as "", not undefined
    • 7. The capability scan checks shape, not spelling
    • 8. Names change without warning
    • 9. Small things that each cost an hour
    • 10. `prompt.compose` is asked every turn, but only its first answer is sent
    • What I couldn't reproduce, and what's fixed
  12. 10
    Recipes

    Nine short patterns you can paste and adapt, each one run at 2.1.286.

    19,509characters
    10 sections
    • 1. A guard that fails closed
    • 2. A redactor on the way back up
    • 3. Keeping the engine for the rest of the session
    • 4. Watching tool calls without getting in the way
    • 5. A status line that keeps itself current
    • 6. Adding a noun other mods can use
    • 7. A pane
    • 8. A command, and coping when it's refused
    • 9. A hook that only wants a say
    • Where to read real ones

What this is not

This isn't Anthropic's documentation and it doesn't speak for them. Theirs went up with 2.1.287, starting at Mods overview, and it's the contract. Read it first. This guide is what the build does around that contract, the traps I hit, and the places the two disagree, each with the output from a real run. Mods in installed plugins load by default from 2.1.287 unless Anthropic switches them off remotely, and CLAUDE_CODE_ENABLE_FUNCTION_HOOKS does nothing any more. The declarations are theirs, and any of it can change in the next release without a word. Error strings and types quoted here come from 2.1.286 unless a page says otherwise.

It doesn't cover every field of every event either. The declarations run to hundreds of kilobytes, and a lot of that is tool inputs you already know. What's here is the part you need and the part that'll surprise you.

Feedback