Skip to main content

Mod API Overview

A mod is a plugin whose code runs inside Claude Code. Claude Code calls the code when an event happens, such as a tool call or a submitted prompt. The code can watch the event, change it, or answer it. The object $ is the Mod API, and the type file that Claude Code publishes marks it as early access, so it may change between releases.

These pages cover 2.1.304. Official pages: Mods Overview, Create a Mod, Use the Mods API, React to Events, Draw in the Interface, Test a Mod, Troubleshoot a Mod, and Mods Reference.

At a Glance​

QuestionAnswer
Can you use it?✅ Yes. Put modules in hooks/hooks.json of a plugin and export register from the module.
Can you change it?✅ Yes. Edit the module. Claude Code reloads it when you save.
Can you turn it on or off?disableAllHooks stops installed mods. --safe-mode and --bare load none. See Files, Nouns, and Gates.
Where does it live?A plugin folder: .claude-plugin/plugin.json, hooks/hooks.json, and the hooks module.
StatusDocumented Differs Differs Gated

Example​

This mod writes each Bash command that Claude runs to the transcript.

hooks/register.js
export function register(on) {
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
$.ui.log('Claude runs: ' + e.command)
return next(e)
})
}

A First Mod​

A small mod has three files.

  • first-mod/
    • .claude-plugin/
      • plugin.json
    • hooks/
      • hooks.json
      • register.js
  • plugin.json is the manifest of the plugin. It has a name, a version, and a description.
  • hooks.json holds { "modules": ["./register.js"] }. That key makes the plugin a mod.
  • register.js is the hooks module. It exports register, and register calls on once for each hook.

Load the folder for one session with the flag --plugin-dir.

claude --plugin-dir ./first-mod

The docs build the same mod step by step in Create a Mod. You can also describe the mod in a session and let Claude write it.

How a Mod Loads​

  1. The plugin has hooks/hooks.json with modules. It holds one path, relative to that file. A second entry is refused.
  2. The engine reads the source of the module before it loads it. It lists the events, the $ calls, the env names, and the $.state values. claude plugin validate <dir> prints that list.
  3. The plugin.register hooks of the modules admitted before it can refuse the module.
  4. The engine.create fold builds $ for the plugin. A step can add a noun.
  5. The engine calls register(on, options) once. Then session.start fires for each loaded mod.
  6. After an edit, /reload-plugins or the reload of --plugin-dir runs the cycle again.

Hooks run in five tiers, from outermost: prepend, user, append, builtin, core. Managed plugins in prependPlugins and appendPlugins take the first and third tier. The engine itself is core.

Commands for Mod Authors​

ItemStatusWhat it does
claude --plugin-dir <dir>DocumentedLoads a plugin folder for one session and reloads its module on save.
claude plugin validate <dir>DocumentedReads the manifest and the module, then lists the events and $ calls. --strict makes warnings errors and --json prints a report.
claude plugin test [dir]DocumentedRuns every *.test.ts and *.test.tsx file. Exits with 1 when a test fails. See Testing.
/pluginDocumentedShows a line such as 1 mod active · first-mod when a mod loaded.
/reload-pluginsDocumentedReloads the plugins of the session.
claude --debug-file <path>DocumentedWrites a log with a line for each module that loads or fails.

If a mod does nothing, run claude plugin validate first, then read the debug log. The docs list the causes in Troubleshoot a Mod.

How to Read the Mod API Pages​

  • The Documented badge means a docs page names the item, or the item is in the published type file. The docs call that file "the complete reference".
  • The Differs badge means the docs and the type file or the program disagree.
  • The Gated badge means a flag or a gate controls the item.
  • In a "Where it can be used" cell, "Run time" means in a hook, in a closure that a hook drew, or in a timer callback. It does not mean inside register.
  • Most calls on $ are also events with the same name, such as fs.read. A hook on that event can pass the call on, refuse it with { deny }, or answer it with { value }.
  • Source for these pages: the program (types-2.1.304.d.ts) and the docs pages above.

Pages of the Mod API​

PageWhat is in it
Hooks, on, and nextregister, on, next, failure, and budgets.
Event Table TypesHow each event gets its input and result type.
Files, Nouns, and GatesManifest keys, the $ nouns, switches, limits, and built-in mods.
Plugin and Engine$.plugin, plugin.register, engine.create, and their types.
UI Methods$.ui: toasts, panes, scroll, focus, clipboard.
UI Eventsui.render, ui.press, and the other interface events.
Surfaces, Elements, and Render SitesWhat a mod may draw, where, and with which props. Also JSX and globals.
Model, Audio, and MCP$.model, $.audio, $.mcp.
Session$.session and the session.* events.
Turn and Prompt$.turn, $.prompt, turn.*, prompt.*, skill.prompt, attribution.text.
Tool, Command, and Config$.tool, $.command, $.config.
Agent$.agent, agent.offer, agent.spawn, and the agent types.
Files, Store, and State$.fs, $.store, $.state, and the state helpers.
Clock, HTTP, Process, Env, and Settings$.clock, $.http, $.process, $.env, $.settings.
Telemetry$.telemetry, telemetry.log, telemetry.mark.
Classic EventsThe classic.* events of the settings hooks.
The claude-code/testing Moduletest, describe, expect, mock, tier, $.ui.mount.

The type pages hold the detailed shapes of inputs and results: Hook Machinery Types, UI Types, Model, Audio, and MCP Types, Session Types, Turn and Prompt Types, Tool, Command, and Config Types, Files, State, Clock, HTTP, Process, and Settings Types, Classic Event Types, Testing Types, and Event Table Types.

Known Gaps​

  • The 50 millisecond limit of a prompt.edit hook is in the docs and not in the type file.
  • The name of the rollout flag for installed mods is not in the program strings.
  • The value re-entry of next.error.kind is in the docs and in a program debug string, and not in the type file.
  • Many doc comments in the type file name code items without backticks. The tables keep the wording of the type file where it matters.