The Navigator · 8 min mission

Slash Commands & Making Claude Code Yours

Build custom commands and tune the interface until it disappears.

commandscustomizationworkflowFact-checked 2026-06-13
On this page

Type a single / in Claude Code and a menu unfolds: dozens of commands for switching models, clearing context, reviewing a diff, configuring permissions. Most people learn five of them and stop. That is the difference between using Claude Code and owning it.

This guide is about that second half. First the built-in commands worth keeping in muscle memory. Then the part that actually makes the tool yours: turning a checklist you keep re-typing into a custom /command that lives in your repo, takes arguments, and ships to your whole team through git. And finally the wider personalization layer — output styles and a custom status line — that reshapes how Claude talks and what your terminal shows you.

How commands work

A command is only recognized at the start of your message — / followed by the command name. Anything you type after the name is passed to the command as arguments. Type / alone to browse the full list, or / plus a few letters to filter it. That is the whole interface: a prefix that routes your message to a named behavior instead of straight to the model.

CommandWhat it does
/helpShow help and the full list of available commands
/clearStart a fresh conversation with empty context. The old one stays in /resume
/compactSummarize the conversation so far to reclaim context, without losing the thread
/contextVisualize where your context window is going as a colored grid, with bloat warnings
/modelSwitch the active model (and, where supported, the effort level)
/initGenerate a starter CLAUDE.md by analyzing the project
/memoryOpen and edit your CLAUDE.md memory files
/configOpen Settings — theme, model, and output style all live here (alias /settings)
/permissionsManage allow / ask / deny rules for tool permissions
/agentsCreate and manage subagent configurations
/rewindRoll the conversation and/or code back to an earlier checkpoint
/doctorDiagnose your install and settings; press f to have Claude fix issues
Built-in commands worth keeping in muscle memory. Verified against the official commands reference.

Your first custom command

Here is the moment custom commands earn their place. You keep typing the same instruction — "write a conventional-commit message for the staged changes," or "review this file for our error-handling conventions." Each time, you re-type the framing. A custom command captures that framing once.

The mechanics are deliberately plain. Drop a markdown file in .claude/commands/ and its filename becomes the command: .claude/commands/commit-msg.md gives you /commit-msg. The body of the file is the prompt Claude runs when you invoke it. No build step, no registration — Claude Code watches those directories and picks the command up.

Where you put the file decides who can use it. A project command in .claude/commands/ ships through version control, so every teammate who clones the repo gets it. A personal command in ~/.claude/commands/ follows you across every project on your machine. Same syntax, different reach — commit the ones your team should share, keep the personal ones in your home directory.

create and run a command
… scroll to run this session
A project command is just a markdown file. Create it, restart is not needed — Claude Code picks up new command files live — then invoke it with a slash.

Passing arguments

A static prompt is useful. A prompt that takes input is where commands start to feel like little programs. The official placeholder for this is $ARGUMENTS — wherever it appears in the command body, Claude Code substitutes whatever you typed after the command name.

So a .claude/commands/fix-issue.md containing Fix GitHub issue $ARGUMENTS following our coding standards. turns /fix-issue 123 into "Fix GitHub issue 123 following our coding standards." One small touch worth knowing: if you pass arguments but the body has no $ARGUMENTS placeholder, Claude Code does not silently drop them — it appends ARGUMENTS: <your input> to the end so Claude still sees what you typed.

When a command needs several distinct inputs, reach for positional arguments. $ARGUMENTS[0] is the first argument, $ARGUMENTS[1] the second, and so on; $0, $1, $2 are the documented shorthands for the same thing. Multi-word values use shell-style quoting, so /migrate "Search Bar" React Vue makes $0 expand to Search Bar (quoted as one) and $1 to React. To put a literal dollar-amount like \$1.00 in your prose without it being treated as an argument, escape it with a backslash.

Frontmatter: configuring the command

The YAML block between --- markers at the top of the file configures how the command behaves. A migrate-component command, for instance, might declare description: Migrate a component from one framework to another and argument-hint: [component] [from] [to], then use $0, $1, and $2 in its body. Every field is optional, but a few are worth setting deliberately.

description is the one to always write — it is the text Claude reads to decide when a skill-backed command is relevant, and it shows in listings. argument-hint is a small but lovely touch: it shows the expected arguments during autocomplete, so argument-hint: [issue-number] reminds you (and your teammates) what to type. allowed-tools pre-approves specific tools while the command is active, so Claude can run them without a permission prompt each time — for example allowed-tools: Bash(git add *) Bash(git commit *) on a /commit command. model pins which model runs this command, useful for routing a cheap, mechanical command to a smaller model.

One field changes behavior in a way beginners trip over: disable-model-invocation: true. Because commands are skills now, Claude can choose to invoke a relevant one on its own. Set this to true for anything with side effects — deploys, commits, anything you want to fire only when you type the slash — so Claude never decides to run it for you.

FieldWhat it controls
descriptionWhat the command does and when to use it — drives autocomplete and Claude’s auto-invocation
argument-hintPlaceholder shown during autocomplete, e.g. [issue-number] or [filename] [format]
allowed-toolsTools Claude may use without asking while this command is active, e.g. Bash(git status *)
modelModel to use when this command runs (otherwise inherits the session model)
disable-model-invocationSet true so only *you* can trigger it — use for deploys, commits, anything with side effects
The frontmatter fields you will reach for most. All are optional; `description` is the one to always include.

Namespacing with subdirectories

As your command library grows, a flat .claude/commands/ folder gets noisy. Subdirectories give you organization for free, and the directory structure flows straight into the command name — a skill at .claude/skills/deploy-staging/SKILL.md becomes /deploy-staging, named from its directory.

Namespacing also keeps shared commands from colliding. Commands and skills that come from a plugin are namespaced as plugin-name:skill-name, so a review command from your acme plugin is /acme:review and can never clash with your own /review. And in a monorepo, project skills load not just from the repo root but from nested .claude/skills/ directories on demand — edit a file in packages/frontend/ and Claude Code also looks for skills defined there. Each package can own its own commands without polluting the global namespace.

Reshaping the voice: output styles

Custom commands change what Claude does on demand. Output styles change how Claude responds, every turn — they modify the system prompt to set role, tone, and output format. Reach for one when you keep re-prompting for the same voice ("explain as you go," "lead with a diagram") instead of asking once per task.

Claude Code ships four built-in styles. Default is the standard software-engineering system prompt. Proactive pushes Claude to act over plan, making reasonable assumptions instead of pausing for routine decisions. Explanatory adds educational "Insights" between steps so you understand the why behind implementation choices. Learning goes further into learn-by-doing: Claude shares insights and leaves TODO(human) markers for you to fill in small, strategic pieces of code yourself.

You pick a style through /configOutput style (the standalone /output-style command was deprecated and then removed; set the outputStyle field in settings if you prefer editing config directly). A custom style is just a markdown file — frontmatter for name and description, then the instructions you want bolted onto the system prompt — saved at ~/.claude/output-styles (personal) or .claude/output-styles (project). By default a custom style drops Claude's built-in coding instructions; set keep-coding-instructions: true when you are only changing how Claude communicates but still want it coding normally.

The status line: your terminal dashboard

The last piece of making Claude Code yours sits at the bottom of the screen. The status line is a customizable bar that runs any shell script you configure and displays whatever it prints — a persistent, at-a-glance view of context usage, session cost, git branch, or anything else you choose.

The fastest way in is the /statusline command: describe what you want in plain language ("show model name and context percentage with a progress bar") and Claude Code writes the script into ~/.claude/ and wires up your settings for you. Under the hood it is a statusLine block in settings.json with type: "command" and a command pointing at your script.

The trick that makes it powerful: Claude Code pipes JSON session data to your script on stdin, and your script prints a line back. That JSON carries model.display_name, workspace.current_dir, session_id, a whole cost object, and a context_window object with a pre-calculated used_percentage — so a one-line jq filter can render a live context-usage bar without you computing anything. Each echo becomes a row, and ANSI color codes work, so a two-line status line with a color-coded context meter is a few lines of bash.

~/.claude/settings.json
json
{
  "statusLine": {
    "type": "command",
    "command": "jq -r '\"[\\(.model.display_name)] \\(.context_window.used_percentage // 0)% context\"'"
  }
}

Three layers, three jobs

CLAUDE.md vs. output style

CLAUDE.md adds a user message after the system prompt — it carries project facts: build commands, conventions, architecture.

An output style modifies the system prompt itself — it sets role and tone for every response. Use CLAUDE.md for what Claude should know; use an output style for how it should talk.

Command vs. output style

A custom command is a saved prompt you fire on demand with /name — one task, when you ask.

An output style applies to every turn until you switch it. Reach for a command to repeat an action; reach for an output style to repeat a manner.

Knowledge check

You write a `/deploy` command in `.claude/commands/deploy.md` that pushes to production. You want it to run only when you explicitly type `/deploy`, never when Claude decides your code "looks ready." What is the right move?

Reach the end and this star joins your charted sky.