← Claude Code Hub
✦ Tip #221 Oct 7, 2026

Claude Code mods: draw your own UI inside Claude Code

A mod is JavaScript or TypeScript that runs inside Claude Code: it draws a line above the prompt or a pane, and can hold a tool call. Claude writes one from a single sentence.

A Claude Code mod draws the craft bar above the prompt: the work, its phase, a square per slice and the agent running now

TL;DR On 2.1.287 or later, ask for make a mod that shows the current git branch above the prompt, pick Enable for this session, and it loads when the turn ends. Before installing someone else's, claude plugin validate lists what it touches.

A mod is a Claude Code plugin written in JavaScript or TypeScript whose functions run inside Claude Code. It can draw a line above the prompt or a pane beside the transcript, add a command that answers on the spot without spending a Claude turn, and hold, rewrite or answer a tool call before it runs. It works in the terminal from 2.1.287 and in the Desktop Code tab from 2.1.286.

If you use Claude Code as your harness and like to tinker, this is the dream: with TypeScript you can add buttons, panes, views and animations, and catch commands and subagents as they happen. The docs are long and on the abstract side, and their examples are deliberately small. So I tried it on something real: a status bar for craft, my development plugin.

Where a mod fits

What it is Where it runs
Settings hook A shell command, HTTP request or prompt fired on an event Outside Claude Code
Skill A markdown file of instructions In what Claude reads
MCP A server that gives Claude tools Outside, as a separate process or service
Mod Functions Claude Code calls on each event Inside Claude Code

Because it lives inside, each of a mod's hooks decides what happens to its event: it observes and lets it through, rewrites it before it continues, or answers it so the usual behavior never runs. For the other mechanisms, the 6 extension points sorts them by the question each one answers.

Ask Claude for a mod

1. Check your version

claude --version

2. Describe it in one sentence

make a mod that shows the current git branch above the prompt

Claude works from the built-in plugin-authoring skill (you can load it yourself with /plugin-authoring) and writes the mod under ~/.claude/dev-mods/<session-id>/. In default and acceptEdits modes it asks you to approve each file, since ~/.claude is a protected path.

3. Turn on hot reloading

When Claude saves the first file, Claude Code asks whether to enable hot reloading for the session. Pick Enable for this session: the mod loads when the turn ends and reloads each time Claude changes it. You'll find it in /plugin, on the Installed tab.

4. Keep it

The session's folder gets cleaned up over time. Copy the mod out and load it wherever you want:

claude --plugin-dir ~/mods/git-branch

This flow is interactive and I didn't capture it here: the steps and names come from the official guide.

A real one: the craft bar

Craft runs subagents that build in phases, and I leave them working. I wanted to see at a glance whether anything was moving, without asking Claude and without spending a turn. The design is one line above the prompt with the work, its phase, a square per slice and the agent running right now:

craft retry · implement · ■■■▣▣□ 3/6 · ⠋ draw 2:14 +1

It's five hooks in a single file, hooks/register.ts, declared in hooks/hooks.json as { "modules": ["./register.ts"] }:

  • command.run on /^craft:/ records the phase when I run /craft:implement, then lets the skill run as usual.
  • agent.spawn on /^craft:/ adds the agent to the line, and turn.complete with the same agentId removes it and marks its slice as built.
  • ui.render on AbovePrompt draws the line with Box and Text, on top of whatever Claude Code already draws there.
  • /craft:bar off is answered by the mod itself, with no Claude turn, and the choice is kept in $.store for every session.
  • session.end clears the state when the session closes.
on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
  const line = pieces(state, await $.clock.now())
  if (e.props.hasSurvey || line.length === 0 || (await hidden($))) return next(e)
  const { Box, Text } = $.ui.resolve(e)
  const below = await next(e)
  const texts = line.map(piece => Text({ ...STYLES[piece.tone], children: piece.text }))
  return Box({ flexDirection: 'column', children: [Box({ key: BAR, children: Text({ children: texts }) }), below] })
})

The first live try, on 2.1.292, showed this while craft built four slices:

craft gamma · implement · □□□□ 0/4

The work, the phase, the four squares, /craft:bar off and on, and staying out of the way of Claude Code's survey all passed. Three things failed: every agent showed up as build, because the slice name sits further down its prompt; two agents spawned in the same tenth of a second overwrote each other, so the +1 never appeared; and the squares never turned green, because the first version matched them by their check command and craft rewrites those commands. The takeaway: events tell you for certain when a subagent starts and ends; what's inside its prompt, they don't. The bar still lives on a working branch, not in the published craft.

Before you install someone else's

A mod isn't sandboxed: it runs with your permissions, can read your secrets, sees every prompt and can approve tool calls for you. claude plugin validate lists the events it handles and the calls it makes, without running it. This is the real output for the craft bar:

❯ ./register.ts hooks: command.run{command=/"^craft:"/}, agent.spawn{subagentType=/"^craft:"/}, turn.complete, session.end, ui.render{component=AbovePrompt}
❯ ./register.ts calls: $.clock.every (via tick), $.clock.now, $.fs.list (via folders), $.fs.read (via readSlices), $.session.root (via folders, readSlices), $.store.get (via hidden), $.store.set (via answerBar), $.ui.invalidate, $.ui.resolve

✔ Validation passed

Two more things: in the VS Code extension's chat panel and in claude -p, hooks run but nothing gets drawn. And /diff, which you may already use, is a built-in mod: cc-plugin-diff.

Official docs: Mods overview

Free guide

The 51 essentials, as a guide.

One page per tip. Five chapters. What I actually use daily in production. No theory, no fluff.

  • I. Getting started 10 tips
  • II. Awareness 3 tips
  • III. Mastery 22 tips
  • IV. Autonomy 10 tips
  • V. Comparison 6 tips
Are you a professional Web developer?

You'll receive the guide by email · You join the Gravitas newsletter · Unsubscribe anytime

of 51
#

Wmedia · 51 Tips
Free guide · 51 tips · 5 chapters

The 51 essentials, as a guide.

Are you a professional Web developer? · Unsubscribe anytime
Workshop for teams

Multiply your team's output without sacrificing quality: a 6 to 8 hour AI First workshop, online, on the Claude platform.

See the workshop

Want the 51 Claude Code essentials as a guide?