# Claude Code Mods: Rewrite the Agent From the Inside

> Claude Code mods explained: in-process JS/TS hooks that draw panes and rewrite tool calls. Your first mod, guard rails, security and team controls.

Source: https://bytevancer.com/blog/claude-code-mods · Published 2026-10-02 · ByteVancer · AI Engineering

**Claude Code now takes mods: a few lines of JS or TypeScript that run inside the agent, redraw its UI and step into tool calls. Your first mod, guard rails, and the security fine print.**

Claude Code just got a mod menu. On October 1, 2026, @ClaudeDevs posted "You can now mod Claude Code" (around 2.6M views at the time we checked): change how it behaves, customize the UI, swap in your own features, with a few lines of TypeScript, or by having Claude build the mod for you. Mods ship inside **plugins**, so you install them with `/plugin` in the CLI or the desktop app. We read the new mods docs and turned them into diagrams, verbatim code and a security checklist. Facts are Anthropic's unless we say otherwise; the jokes are ours.

## TL;DR

- A mod is a plugin made of JavaScript or TypeScript event handlers that run inside Claude Code, not as an outside script.
- Each handler can observe an event, rewrite it, or answer it outright (so the tool never runs).
- Mods can draw: a pane, a band above the prompt, a status line, toasts, and restyled built-in pieces like the spinner. Not the permission prompt.
- Needs Claude Code v2.1.287 or later, where mods are on by default. Review any mod with `claude plugin validate` before you install it.
- Mods are not sandboxed. A mod runs with your permissions and can approve a tool call before you're asked. Install like you'd run a stranger's script: carefully. 🫡

## What dropped

The requirement is short: **Claude Code v2.1.287 or later**, and mods are on by default. If you were in early access, the `CLAUDE_CODE_ENABLE_FUNCTION_HOOKS` flag is now ignored. Mods work in the CLI and in the Code tab of Claude Desktop. Installing one looks like any other plugin:

*From Anthropic's mods overview.*
```bash
/plugin install token-chart@your-org
# or, from your shell
claude plugin install token-chart@your-org
# installed from the shell mid-session? then run
/reload-plugins
```

Once something is loaded, `/plugin` shows a dim line like `1 mod active · first-mod`. Runtime Wire's Ryan Merket flagged the headline risk on launch day: mods are unsandboxed and run with full machine privileges. More on that below.

## What a mod actually is

Anthropic's one-liner: "A mod is a plugin that changes how Claude Code looks and behaves." Under the hood it's a set of event handlers. When something happens (a tool call, a submitted prompt, part of the interface being drawn), Claude Code calls your handler, and your handler can watch, change, or take over. The big difference from the hooks you already know: settings hooks (a shell command, HTTP call or prompt in your settings file) run outside Claude Code. A mod's handlers are functions that run inside it.

**One event through the mod chain**
Event fires → Your hook runs → Pick a move → next() passes it on → Claude Code acts

1. **Event fires** — e.g. tool.call: Claude is about to run Bash.
2. **Your hook runs** — It gets ($, e, next): the mods API, the event, and the rest of the chain.
3. **Pick a move** — Observe: return next(e). Rewrite: call next with a changed copy. Answer: return a result without next.
4. **next() passes it on** — Guard and org mods first, then mods you install, then appended and built-in mods.
5. **Claude Code acts** — Unless a hook answered first, in which case the tool never runs.

One more rule makes mods reviewable: to do anything outside its own code (draw, add a command, call a model, read a file, start a process, hit the network), a mod has to go through the mods API, `$`. That's why Claude Code can list what a mod does before you install it. In [harness engineering](https://bytevancer.com/blog/what-is-harness-engineering) terms, a mod is harness customisation that runs inside the agent itself; our [harness vs loop vs graph breakdown](https://bytevancer.com/blog/harness-vs-loop-vs-graph-engineering) helps you pick which layer to mod first.

## Your first mod: count tool calls

The docs' starter mod adds a /tally command and shows a live tool-call count in the spinner. No Node.js install, no bundler, no build step: Claude Code loads .js and .ts files directly. Three files:

*File layout, from Anthropic's "Create a mod" page.*
```text
first-mod/
├── .claude-plugin/
│   └── plugin.json
└── hooks/
    ├── hooks.json
    └── register.js
```

*hooks/hooks.json: points Claude Code at the module.*
```json
{
  "description": "The first-mod hooks module",
  "modules": ["./register.js"]
}
```

*hooks/register.js, verbatim from Anthropic's "Create a mod" docs.*
```javascript
// The count, shared by the hooks below
let calls = 0

// Claude Code calls this once when the mod loads
export function register(on) {
  // Runs when the session starts, before your first prompt
  on('session.start', async ($, e, next) => {
    // Add the /tally command
    await $.command.register({
      name: 'tally',
      description: 'Show how many tool calls Claude has made',
    })
    // Let the session start as usual
    return next(e)
  })

  // Runs each time Claude is about to use a tool
  on('tool.call', async ($, e, next) => {
    calls += 1
    // Ask Claude Code to draw the interface again, so the new count shows
    $.ui.invalidate('ui.render')
    // Let the tool run as usual
    return next(e)
  })

  // Runs when you type /tally, and only then, because of the matcher
  on('command.run', { command: 'tally' }, async () => {
    // The text to print in the transcript
    return { text: 'Claude has made ' + calls + ' tool calls since this mod loaded' }
  })

  // Runs each time Claude Code draws the spinner
  on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
    // Keep Claude Code's spinner, with the count added after its word
    return next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } })
  })
}
```

Load it with `claude --plugin-dir ./first-mod`. The spinner now reads like `Thinking · tool calls: 2…`, and `/tally` prints `first-mod: Claude has made 2 tool calls since this mod loaded`. It hot-reloads on save (each reload resets the count to 0, because module variables are lost on reload). Notice the module variable `calls`: that's how hooks share data with each other.

**🎞️ first-mod, live**
1. **SPINNER** — Thinking · tool calls: 1… — Claude reaches for its first tool.
2. **SPINNER** — Thinking · tool calls: 2… — tool.call fires, the count goes up, the UI redraws.
3. **SPINNER** — Thinking · tool calls: 3… — Still Claude's spinner, just with a suffix.
4. **/tally** — first-mod: Claude has made 3 tool calls since this mod loaded — No Claude turn needed. Just your code. 😌

*Dramatised from the docs' first-mod example (the docs show 2 tool calls; we let it run to 3).*

Before you trust any mod, including this one, run the validator. It statically lists every hook and every API call:

*Output of claude plugin validate ./first-mod, per the docs.*
```text
  ❯ ./register.js hooks: session.start, tool.call, command.run{command=tally}, ui.render{component=Spinner}
  ❯ ./register.js calls: $.command.register, $.ui.invalidate

✔ Validation passed
```

To keep that analysis honest, write every `$` call in full and event names as string literals. Claude Code also writes .d.ts types into `.claude-plugin/types/` (the docs say trust those over any page), and `claude plugin test` runs *.test.ts files with no session, sign-in or network.

### Or let Claude write it

Too lazy for three files? Valid. Claude Code has a built-in `plugin-authoring` skill. Ask something like "make a mod that shows the current git branch above the prompt" and Claude writes it to `~/.claude/dev-mods/<session-id>/<name>/`, then Claude Code asks whether to enable hot reloading for this session ("Enable for this session" or "Not now"). Mods Claude writes load only in that session; to keep one, copy it out and run it with `claude --plugin-dir ~/mods/git-branch`.

## Where mods can draw

This is the part no settings hook can touch. A mod gets UI elements (Box, Text, Button, Link, Code, Markdown, Input, Select and more) from `$.ui.resolve(e)`, or writes JSX in .tsx/.jsx files. Here's the screen map from the interface docs:

**Render sites a mod can draw in (per Anthropic's interface docs)**
- **Your mod** — Draws through $.ui; every pixel goes through the API.
  - **Pane** — A sidebar on the right in a wide fullscreen terminal; a framed region above the prompt otherwise.
  - **AbovePrompt band** — A band above the prompt, shared by every mod.
  - **Status · toast · log** — $.ui.status line under the prompt, $.ui.toast top right, $.ui.log as a dim transcript line Claude doesn't read.
  - **Built-in sites** — Spinner, ToolUse, ToolResult, messages, AskUserQuestion, PromptHint, TurnDuration and more.
- Finally **Off-limits: the permission prompt** — It is not a render site. A mod can restyle much of the UI, but not that.

State lives in a module variable (lost on reload), `$.state` (per session, reactive) or `$.store` (persists, 4 MiB). Gotcha: a pane a mod opens by itself only shows in a terminal at least 144 columns wide (110 once you've opened it yourself).

## Guard rails you can build

The events docs ship three guard patterns. All verbatim, all on the tool.call / tool.check events. First, the hard no:

*Deny force pushes: the hook answers the event, so Bash never runs. From Anthropic's events docs.*
```javascript
// The matcher limits the hook to Bash calls, so e.command is the shell command
on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
  if (/git push .*--force/.test(e.command)) {
    // Returning without calling next answers the event, so the command never runs
    return { deny: 'Force pushes are not allowed in this repository. Push to a new branch instead.' }
  }
  // Every other command goes on to the permission check and then to Bash
  return next(e)
})
```

Second, hold the call and ask a human. The tool call literally waits on your answer:

*Hold risky commands with $.ui.ask, from Anthropic's events docs. Note: this RISKY regex misses forms like git push -f.*
```javascript
const RISKY = /\brm\s+-rf?\b|\bgit\s+reset\s+--hard\b|\bgit\s+push\b.*--force/

export function register(on) {
  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
    // Let every other command through without a question
    if (!RISKY.test(e.command)) return next(e)
    // Start from the safe answer, so a question nobody answers refuses the command
    let answer = 'Refuse'
    try {
      // The tool call waits here until the user picks one of the two labels
      answer = await $.ui.ask('Run this command? ' + e.command, ['Run it', 'Refuse'])
    } catch {
      // The user dismissed the question, or this is a claude -p run with nobody to ask
    }
    if (answer !== 'Run it') {
      // Answer without calling next, so the command doesn't run
      return { deny: 'The user declined this command. Ask before trying a different approach.' }
    }
    return next(e)
  })
}
```

Third, tool.check: change what the permission check decided. This one denies git push while you're on main:

*From Anthropic's events docs.*
```javascript
on('tool.check', { tool: 'Bash' }, async ($, e, next) => {
  // What the permission rules and settings hooks decided: 'allow', 'ask', or 'deny'
  const decided = await next(e)
  if (!e.input.command.includes('git push')) return decided
  const branch = await $.process.run(['git', 'branch', '--show-current'])
  if (branch.stdout.trim() !== 'main') return decided
  return { decision: 'deny', reason: 'Push from a branch other than main' }
})
```

> **A mod is a reminder, not branch protection** — Anthropic's docs say to treat the tool.check example as a reminder for Claude; to block pushes to main for everyone, protect the branch on your Git host. Regexes are easy to sidestep too (git push -f slips past RISKY). Mods catch honest mistakes; server-side rules are the wall.

The same page also has a `prompt.submit` hook that adds your git branch to context when a prompt mentions a PR, and a `turn.step` hook that logs prompt-cache usage (turn.step can even route a request to a different model). One catch: a hook that throws is skipped (fails open) unless you add `.catch(...)`. For a guard, fail closed.

## Mods vs settings hooks vs skills vs MCP

**From the comparison table in Anthropic's mods overview. A single plugin can hold all four.**
- **What it is** — Mod: Functions in a plugin that Claude Code calls in its own process; Settings hook: Shell command, HTTP call or prompt run on a lifecycle event; Skill: SKILL.md instructions Claude reads; MCP server: External process that gives Claude tools
- **What it can change** — Mod: Tool calls, prompts, commands, turns, what the interface draws; Settings hook: Whether a tool call or prompt goes ahead, args and results, context; Skill: What Claude knows and does; MCP server: Which tools Claude has
- **Draws in the interface** — Mod: Yes; Settings hook: No; Skill: No; MCP server: No
- **You write** — Mod: JS or TS; Settings hook: A script + a settings.json entry; Skill: Markdown; MCP server: A server in any language
- **Pick it when** — Mod: You want a pane, a band, a custom command, or to rewrite an event; Settings hook: You want to block, allow or log with a script you already have; Skill: You keep pasting the same instructions; MCP server: Claude needs an external system

## Where mods run

**Per Anthropic's mods overview.**
- **claude in a terminal (incl. editor terminals, JetBrains plugin)** — Hooks run: Yes; Drawing appears: Yes
- **Claude Desktop Code tab (not WSL sessions)** — Hooks run: Yes; Drawing appears: Yes, except terminal-only elements
- **WSL session in Desktop** — Hooks run: No (plugins not available); Drawing appears: No
- **VS Code extension chat panel** — Hooks run: Yes; Drawing appears: No
- **claude -p and the Agent SDK** — Hooks run: Yes; Drawing appears: No
- **Remote Control from claude.ai or mobile** — Hooks run: Yes, on your machine; Drawing appears: In the terminal on your machine
- **Cloud session** — Hooks run: Yes, for a plugin that reaches it; Drawing appears: No

Guard rails work almost everywhere, headless included; the UI fun is terminal and Desktop only.

## Security: read this before you install anything

> **"A mod is code that runs with your permissions."** — That's Anthropic's line: mods aren't sandboxed. A loaded mod can act as you (files, programs, network), read your secrets (env vars, API keys in settings), see every prompt and tool call, rewrite them, submit prompts as you, approve a tool call before you're asked, and spend your usage on model calls. Claude's sandbox covers Claude's Bash, not processes a mod starts, and deny rules don't cover a mod's own `$.fs` calls (Read(.env) denied? A mod can still read .env). It can't change the permission prompt. Before installing, run `claude plugin validate ./some-mod` and read the hooks: and calls: lines. Kill switches: one mod via /plugin → Installed, all mods for a session with `--safe-mode`, or everywhere with `"disableAllHooks": true` in ~/.claude/settings.json.

**Mod limits, per Anthropic's mods reference**
- **10 s** Hook time per event — Time inside next or API calls isn't counted, except $.clock.sleep.
- **1 s** .catch handler — All session.end hooks together get 1.5 s.
- **30 s → 10 min** $.process.run — 30 seconds by default, 10 minutes max.
- **1,024 tokens** $.model.complete — Default maxTokens; up to 64,000 or the model's limit.
- **4 MiB** Storage — Per file for $.fs.read/write; total for $.store.
- **10/s** Redraws — 30/s in a terminal for a visible pane, an expanded band or the hint line.

*Also from the reference: toasts last 4 seconds by default, and names are letters, digits, _ and -, up to 64 characters.*

## Team and enterprise controls

Org admins get a built-in guard, `sec-default@builtin`. It loads ahead of user mods when the machine has managed settings or a Team or Enterprise sign-in, protecting managed hooks, the system prompt, managed CLAUDE.md, settings reads and managed MCP tools. There, deny rules beat user mods, and managed PreToolUse hooks run first with a final block.

**Which mods setting do you need? (per Anthropic's admin docs)**
- Only org-approved mods (plus built-ins) should load? → **allowManagedModsOnly, an option on the sec-default guard**
- Block --plugin-dir, --plugin-url and mods Claude writes? → **disableSideloadFlags**
- Org mods must run before or after user mods? → **prependPlugins / appendPlugins**
- User mods should be able to override deny rules? → **allowModsToOverrideDenyRules (otherwise deny rules win)**
- No hooks except managed ones, or none at all? → **allowManagedHooksOnly (wider), disableAllHooks (widest)**
- Otherwise → **Leave the defaults: the sec-default guard already loads ahead of user mods on managed or Team/Enterprise machines**

For finer policy, write a policy mod: the `plugin.register` event shows each mod's `e.uses.calls` and `e.tier`, and returning `{ refuse: reason }` keeps that mod from loading. Mods that review mods. Very meta.

## How other coding agents do hooks

Hooks aren't new; Codex, Gemini CLI and Cursor all have them. What differs is where the code runs and whether it can touch the UI. Here's each tool as its own docs describe it today (we checked all four on October 2, 2026):

**Per each vendor's hooks docs, checked Oct 2, 2026. Docs change fast; re-check before you pick a tool on this.**
- **Claude Code mods** — How hooks run: JS/TS functions inside Claude Code's process; Where they're configured: A plugin (hooks/hooks.json); Example events: tool.call, tool.check, prompt.submit, ui.render; UI drawing: Yes: pane, band, status line, toasts, built-in sites
- **OpenAI Codex CLI** — How hooks run: Command scripts or MCP tool calls, returning JSON; Where they're configured: hooks.json or config.toml in ~/.codex or <repo>/.codex; plugins can bundle hooks; Example events: SessionStart, PreToolUse, PermissionRequest, PostToolUse, Stop; UI drawing: None described
- **Google Gemini CLI** — How hooks run: Scripts or programs over stdin/stdout JSON; on by default since v0.26.0; Where they're configured: settings.json; extensions can bundle hooks; Example events: BeforeAgent, BeforeModel, BeforeTool, AfterTool, PreCompress; UI drawing: None described
- **Cursor** — How hooks run: Processes over stdio JSON, command- or prompt-based; Where they're configured: .cursor/hooks.json or ~/.cursor/hooks.json; Example events: beforeShellExecution, preToolUse, afterFileEdit, stop; UI drawing: None described (returns text messages only)

As those docs describe things today, the others run external commands or processes that answer yes, no or "here's some context". Claude Code's mods add in-process functions plus a UI surface: more power to build with, and more power for a bad mod to abuse.

## Built-in mods and the official samples

Fun fact: you're already running mods. Open `/plugin` → Installed → Built-in and you'll see them. Even `/diff` is a mod now (Runtime Wire noticed too). Note that disableAllHooks, --bare and --safe-mode don't stop built-in mods.

The list: cc-plugin-agents-md (loads AGENTS.md as project instructions), cc-plugin-diff (/diff and its pane), cc-plugin-plugin-authoring (the plugin-authoring skill, no mod code), cc-plugin-sec-default (guards what your org manages), cc-plugin-telemetry (analytics records) and cc-plugin-you-should-know (a side agent that watches your back on longer tasks and leaves a note above the prompt; off by default).

Anthropic also put three sample mods in the [claude-code-playground repo](https://github.com/anthropics/claude-code-playground/tree/main/claude-code/mods), shared as-is with no support: **token-weather** (a forecast of your context window above the prompt), **blast-radius** (holds a risky shell command like rm -rf, a force push, git reset --hard or a migration, shows what it would change, with Proceed and Cancel buttons) and **replay-theater** (adds /replay to step through the file edits Claude made last turn, one diff at a time).

## Two starter mods to steal (as sketches)

Two mods that earn their spot on day one. These are our sketches against the API shapes in Anthropic's docs, not code from the docs, and we haven't run them.

**Starter mods: vibe-coder vs team lead**

**🎧 Vibe-coder lane** *(illustrative sketch · untested)* — A context meter in the AbovePrompt band, so you see the window filling before the vibes run out. Uses `$.session.usage()`, which the API docs say returns context tokens, window and percent, plus a Text element from `$.ui.resolve(e)`.

```javascript
// Illustrative sketch, not from Anthropic's docs. Untested.
// Check .claude-plugin/types/ for the exact render return shape.
export function register(on) {
  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
    // The band is shared by every mod — check the types; you may want to compose with await next(e)
    const usage = await $.session.usage()
    const { Text } = $.ui.resolve(e)
    return Text({ children: ['context ', usage.context.percent + '% of ' + usage.context.window] })
  })
}
```

**🛡️ Team-lead lane** *(illustrative sketch · untested)* — A blast-radius-style hold: the docs' $.ui.ask pattern, with the regex widened to catch git push -f and migrations. Proceed or Cancel, a log line when someone proceeds, and a safe default if nobody answers.

```javascript
// Illustrative sketch, not from Anthropic's docs. Untested.
const RISKY = /\brm\s+-rf?\b|\bgit\s+reset\s+--hard\b|\bgit\s+push\b.*(--force|\s-f\b)|\bmigrate\b/

export function register(on) {
  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
    if (!RISKY.test(e.command)) return next(e)
    let answer = 'Cancel'
    try {
      answer = await $.ui.ask('Blast radius check: ' + e.command, ['Proceed', 'Cancel'])
    } catch {}
    if (answer !== 'Proceed') return { deny: 'Held by the blast-radius check. Ask the user first.' }
    $.ui.log('proceeded: ' + e.command)
    return next(e)
  })
}
```

*Both panels are ByteVancer's illustrative sketches, not code from Anthropic's docs, and untested. For the real thing, start from the official token-weather and blast-radius samples.*

TL;DR of the TL;DR: mods turn Claude Code from an app you configure into an app you program. Huge for guard rails and dashboards, and a fresh supply-chain surface next to your secrets. Validate before installing, fail closed, keep real protection on your Git host. Then make the spinner say something unhinged. 🫡

## Frequently asked questions

**What are Claude Code mods?**
Mods are plugins made of JavaScript or TypeScript event handlers that run inside Claude Code. When an event happens, such as a tool call, a submitted prompt or part of the interface being drawn, Claude Code calls the handler, which can observe it, rewrite it, or answer it so the original action never runs. Mods can also draw panes, a band above the prompt, status lines and toasts, and add commands. Anthropic announced them on October 1, 2026.

**Which Claude Code version supports mods?**
Claude Code v2.1.287 or later, where mods are on by default. The CLAUDE_CODE_ENABLE_FUNCTION_HOOKS flag from early access is ignored from that version on. Mods work in the CLI and in the Code tab of Claude Desktop, but not in WSL sessions in Desktop, where plugins aren't available.

**Are Claude Code mods safe?**
Only as safe as their author. Anthropic's docs say a mod is code that runs with your permissions and isn't sandboxed: it can read files and secrets, run programs, use the network, see every prompt and tool call, and approve a tool call before you're asked. It can't change the permission prompt. Review a mod with claude plugin validate before installing, and install only from sources you trust.

**What's the difference between a mod and a Claude Code hook?**
A settings hook is a shell command, HTTP call or prompt in your settings file that runs outside Claude Code on a lifecycle event; it can allow or block a tool call or prompt, change its arguments or result, and add context. A mod's handlers are functions running inside Claude Code: they can also rewrite commands and turns, add slash commands, call a model, and draw in the interface — drawing is something no settings hook can do.

**How do I turn Claude Code mods off?**
Disable one mod from the Installed tab of /plugin, all mods for one session with --safe-mode, or all mods in every session with "disableAllHooks": true in ~/.claude/settings.json, which also stops settings hooks and a custom status line. Built-in mods keep running either way. Organizations can restrict mods with settings such as allowManagedModsOnly and disableSideloadFlags.

## Keep reading

- [Claude Code Effort Levels: Low, Medium, High or Max?](https://bytevancer.com/blog/claude-code-effort-levels) — Claude Code effort levels explained: what low to max really change, real build times, Terminal-Bench 3.0 results and a cheat sheet for picking a level.
- [Harness vs Loop vs Graph Engineering: Which Layer Is Broken?](https://bytevancer.com/blog/harness-vs-loop-vs-graph-engineering) — Harness vs loop vs graph engineering for AI agents: what each layer does, how they nest, and a symptom table to find which one your agent needs fixed.
- [All ByteVancer engineering articles](https://bytevancer.com/blog)

## Want guard rails and dashboards built into your AI tooling?

We build AI-powered cloud applications and the developer tooling around them: agent workflows with real checks, safe defaults and the visibility your team needs. See our [custom AI developer tooling for cloud apps](https://bytevancer.com/services/cloud-applications) or [talk to the team](https://bytevancer.com/contact).

## Sources

- [@ClaudeDevs on X — "You can now mod Claude Code" (Oct 1, 2026)](https://x.com/ClaudeDevs/status/2105721434807083061)
- [Claude Code docs — Mods overview (checked Oct 2, 2026)](https://code.claude.com/docs/en/plugins/mods/overview)
- [Claude Code docs — Create a mod](https://code.claude.com/docs/en/plugins/mods/create)
- [Claude Code docs — React to events](https://code.claude.com/docs/en/plugins/mods/events)
- [Claude Code docs — Draw in the interface](https://code.claude.com/docs/en/plugins/mods/interface)
- [Claude Code docs — Use the mods API](https://code.claude.com/docs/en/plugins/mods/api)
- [Claude Code docs — Manage mods for your organization](https://code.claude.com/docs/en/plugins/mods/admin)
- [Claude Code docs — Mods reference (limits)](https://code.claude.com/docs/en/plugins/mods/reference)
- [GitHub — anthropics/claude-code-playground sample mods (shared as-is, no support)](https://github.com/anthropics/claude-code-playground/tree/main/claude-code/mods)
- [GitHub — anthropics/claude-code built-in mod source](https://github.com/anthropics/claude-code/tree/main/mods)
- [Ryan Merket — Anthropic's Claude Code mods, Runtime Wire (Oct 1, 2026)](https://runtimewire.com/article/anthropic-claude-code-mods-typescript-permissions)
- [OpenAI Codex docs — Hooks (checked Oct 2, 2026; now served at learn.chatgpt.com/docs/hooks)](https://developers.openai.com/codex/hooks)
- [Gemini CLI docs — Hooks (checked Oct 2, 2026)](https://geminicli.com/docs/hooks/)
- [Google Developers Blog — Tailor Gemini CLI to your workflow with hooks (Jan 28, 2026)](https://developers.googleblog.com/tailor-gemini-cli-to-your-workflow-with-hooks/)
- [Cursor docs — Hooks (checked Oct 2, 2026)](https://cursor.com/docs/hooks)

---

*This is the Markdown copy of https://bytevancer.com/blog/claude-code-mods — the page itself has the interactive charts and diagrams.*
