Claude Code mods: what developers, designers, and managers can use them for

Claude Code mods: what developers, designers, and managers can use them for

What mods in Claude Code are, how they differ from hooks, and how developers, designers, PMs, QA, and ops could use them. Plus what to check before installing someone else's mod.

Jakub Kontra
Jakub Kontra
Developer

Claude Code has hooks: shell scripts that run before or after a tool call and can, say, block git push --force to main. A separate guide covers how to set them up. On October 1, 2026, Addy Osmani introduced another layer on the claude.dev blog: mods.

Osmani describes mods as "a way to fit Claude Code to how you work." A mod is a piece of JavaScript or TypeScript that runs directly inside Claude Code. It doesn't just react to events, it can also rewrite them or handle them itself. And it can draw its own UI: a pane next to the conversation, a band above the prompt, buttons. You don't even have to write it yourself, you can just describe it to Claude.

One thing is easy to miss in the excitement: a mod runs with your permissions.

What a mod is and how it differs from a hook

The blog sums it up in one sentence: "Under the hood, mods are hooks, and they ship inside plugins." So a mod is a set of JS or TS handlers distributed inside a plugin. Claude Code calls them on an event, such as a tool call or a submitted prompt. (The documentation goes into detail.)

Osmani describes the difference from classic hooks like this: "A settings hook runs a shell command for each event and passes JSON over stdin and stdout. A mod is loaded once and stays in the session." Settings hooks aren't going anywhere, though. The admin documentation says explicitly: "Nothing about them is deprecated."

A handler receives $ (the Claude Code API), e (the event data), and next (the next handler in the chain, similar to middleware). That lets it watch the event (Observe), change it (Rewrite), or handle it itself (Answer). The example below combines all three in one handler and is based on an example from the events documentation:

export function register(on) {
  on('tool.call', { tool: 'Bash' }, async ($, e, next) => {
    // Answer: handles the event itself, doesn't call next
    if (/git push .*--force/.test(e.command)) {
      return { deny: "We don't let the agent force push." }
    }
    // Rewrite: passes a modified event along
    if (e.command.startsWith('npm ')) {
      return next({ ...e, command: e.command.replace(/^npm /, 'pnpm ') })
    }
    // Observe: writes the command to the transcript and lets it through
    $.ui.log('Bash: ' + e.command)
    return next(e)
  })
}

$.ui.log adds a dimmed line to the transcript that Claude doesn't read.

A simplified comparison with other ways to extend Claude Code, based on the documentation:

ModSettings hookSkillMCP server
Written inJavaScript, TypeScriptshell command (or an HTTP request or a prompt)Markdownany language
How it runsloaded once, keeps state for the whole sessionruns again on every eventinstructions for Claudeseparate server with tools
Draws its own UIyesnonono

All four can be bundled into a single plugin.

What a mod can do

A mod can draw into a side pane, a band above the prompt, the status line, and short pop-up notifications (toasts). It can also register slash commands and tools for Claude, spawn processes, make HTTP calls, and send a standalone request to a model, such as the cheap Haiku. The full list is in the reference.

The blog shows three example mods:

  • Token Weather draws the "weather" of the context window above the prompt: how full it is as a percentage and the trend over the last 12 turns (a turn is one Claude response).
  • Blast Radius holds a risky command like rm -rf, git reset --hard, or a force push, does a dry run, and shows the impact in a pane with Proceed and Cancel buttons.
  • Replay Theater records file edits during a turn and lets you step through them diff by diff with the /replay command.

Before you pick by role

One condition applies to all the ideas below: a mod's UI exists only inside Claude Code. Hooks and UI both work in the CLI (including the terminal in your editor and in JetBrains) and in the Code tab of the Claude desktop app, where you can do without a terminal. In the VS Code chat panel, in claude -p, in the Agent SDK, and in the cloud, only the hooks run, without UI. In a Desktop WSL session, mods don't run at all.

You can just describe a mod to Claude and it will write it using the built-in plugin-authoring skill. But a mod made this way only loads in that session; for permanent use, you have to copy it into your own plugin. And read the code, because it will run with your permissions.

Everything below is ideas built on the capabilities above, not finished mods. The documentation examples I refer to are on the Mods API page.

Developers

The fastest start is to take one of the examples from the blog and have Claude adapt it to you. Beyond that:

  • A safety net for destructive commands modeled on Blast Radius, just with your team's own rules: terraform destroy, prisma migrate reset, or deleting branches.
  • CI and PR status in the status line, refreshed every minute via gh pr checks (example in the documentation).
  • Context budget: a band warning you that compaction is coming. $.session.usage() returns data on context, limits, and cost.
  • Change scope guard: a toast when Claude edits a file outside the directory it's supposed to be working in.

Graphic and UI designers

A mod doesn't draw into Figma or other apps, but it can pull data over HTTP. If a designer uses Claude Code to work on the frontend or a design system, these are worth considering:

  • Design token guard: when CSS or a component is edited, it flags a hardcoded color or pixel values outside the tokens with a toast. Or it holds the write and lets you decide with a button.
  • Check against Figma: the same guard, except it compares against values pulled through the Figma REST API. It needs a Figma access token for that.
  • Palette preview in a pane: in the desktop app via the Svg element, in the terminal via Raster made of colored cells.
  • An /a11y-check command: runs a local contrast check or lint and shows the result in a pane.
  • A brief form in a pane: a few fields and selects (component, variant, breakpoint) that the mod sends to Claude as a prompt once submitted.

Management and PMs

If a PM uses Claude Code themselves, these ideas make sense:

  • /standup: a summary of changes over the last N days from git, optionally polished by a model (example in the documentation).
  • /triage: a cheap model classifies a ticket's text as a bug, feature, or question (example in the documentation).
  • A "ticket lookup" tool for Claude, connected over HTTP to an internal tracker, so Claude knows the ticket's status while it works.

For a manager, the team level is more interesting. Mods are distributed inside plugins through a marketplace, so a team can maintain its own repository with a set of mods as a shared standard: the same safety nets, the same commands. That leads to decisions that belong to the manager:

  • Who writes, reviews, and maintains the mods. It's code that runs on the whole team's machines.
  • How much they're allowed to cost. Every model call from a mod draws on the user's plan or API key.
  • Whether to allow only approved mods. A company can enforce this with the allowManagedModsOnly setting; the technical details are in the security section.

QA and ops

For QA, an obvious option is a mod that runs the tests affected by the changes after every turn and shows the result in a pane. The same logic can also be registered as a manual /test-affected command. Watch out with longer suites: spawning a process has a default timeout of 30 s. A second idea is to deny a commit or push until the tests pass, with the reason stated in the denial.

For ops, the closest fit is Blast Radius for production: the mod holds kubectl or terraform with a production context and lets you confirm it with a button. There's also a status line with on-call or incident status, refreshed over HTTP, and a policy mod that, for example, logs tool calls. How to wire up a mod like that is covered in the admin documentation.

Security: a mod runs with your permissions

The blog says a mod runs "in a sandbox of its own, with no DOM and no Node." At the same time, the documentation says "Mods aren't sandboxed." Both are true, they're just about different things. The JS runtime is isolated, the permissions aren't. Through $, a mod works with files, processes, and the network just like you do.

Osmani adds that a mod is written by its publisher, not by Anthropic. According to the documentation, a mod sees all prompts and tool calls, can rewrite them, can send a prompt on your behalf, approve a tool call without asking, and spend from your plan. Bash sandboxing doesn't apply to processes spawned by a mod. What a mod can't change is the content of the permission prompt.

For readers of the hooks guide, here's an important clarification: a mod can override a hook from regular settings files, but not a company hook from managed settings.

In more detail for admins: a mod can return allow and approve a call that was blocked by a PreToolUse hook outside managed settings, or that an ask rule would have sent for confirmation. A block from PreToolUse hooks in managed settings is final; those run before all mods. deny rules take precedence only where the built-in sec-default guard is loaded (a machine with managed settings, or a Team or Enterprise plan), and even there they don't cover files and processes the mod handles itself. On top of that, neither a hook nor a mod replaces protection on the server. Next to the push-blocking example, the documentation says: "To block pushes to main for everyone, protect the branch on your Git host."

What this means in practice:

  • Treat other people's mods like third-party packages. Osmani advises: "read the repo first and only install from people you trust."
  • Run claude plugin validate before installing. Using static analysis, it lists which events the mod reacts to and what it calls, without running it.
  • If something looks off, disable a single mod via /plugin, all of them for one session with --safe-mode, or permanently with "disableAllHooks": true, which also disables regular hooks.
  • In a company, an admin can allow only the organization's mods and built-in mods (allowManagedModsOnly) and add their own policy mod. Details are in the admin documentation.

How to get started

According to the blog, you need Claude Code 2.1.287 or newer, and mods are enabled by default. A plugin with a mod consists of a .claude-plugin/plugin.json manifest, a hooks/hooks.json file pointing to the module, and the module itself with a register function, with no Node and no build step. You test it with claude plugin test and debug it with claude --debug.

Conclusion

Mods move Claude Code from a tool you configure to a tool you rebuild.

If you want to start, pick one specific annoyance from your own workflow, describe it to Claude, and read the resulting code before you let it run permanently.