Claude Code

Custom slash commands in Claude Code: turn repeated prompts into one-liners

TL;DR

A custom slash command is a Markdown file in your repo, invoked as /name, with arguments and optional shell output injected before the prompt. Now merged into skills; keep allowed-tools narrow and beware untrusted input.

Some prompts you type over and over every day: "review the staged diff against the team's standards", "read issue #123, fix it and write tests", "summarise this PR for reviewers". Each time you phrase it differently, and the results differ too. Claude Code lets you package those prompts as custom slash commands: a Markdown file in the repo, invoked with /command-name, with parameters, able to run shell commands to fetch real data before sending to the model. This post summarises how to do it per the official docs, plus a few templates you can use right away.

Where do commands live?

LocationCreatesUse when
.claude/commands/review.md/reviewA shared team command, committed to the repo
.claude/commands/frontend/component.md/frontend:componentGrouping commands by subfolder (namespace)
.claude/skills/review/SKILL.md/reviewYou need supporting files, or want Claude to load it automatically when relevant

According to the current docs, custom commands have been merged into skills: files in .claude/commands/ still work as before, but Anthropic recommends skills for new work. If a skill and a command share a name, the skill wins. Commands remain the lightest starting point: one file, no folder.

Anatomy of a command

YAML frontmatter is optional; below it is the prompt:

---
description: Fix a GitHub issue following the repo's conventions
argument-hint: [issue-number]
allowed-tools: Bash(gh issue view *) Bash(git *) Read Edit
model: sonnet
---

Read issue #$ARGUMENTS:
!`gh issue view $ARGUMENTS`

Then:
1. Summarise the request in 3 lines
2. Fix the code, write tests for the case in the issue
3. Run the tests, then create a commit referencing the issue
FieldMeaning
descriptionA short description shown in the menu that also helps Claude know when to use it. Put the key idea first.
argument-hintParameter hint shown in autocomplete, e.g. [issue-number].
allowed-toolsTools usable without asking permission, only during this command's turn.
modelModel used for this turn only (doesn't override settings). Useful for pushing simple work to a cheaper model.

Parameters: $ARGUMENTS and $0, $1

  • $ARGUMENTS: everything after the command name. /fix-issue 123 → 123.
  • $0, $1… (or $ARGUMENTS[N]): positional parameters, numbered from 0. Wrap parameters containing spaces in double quotes.
  • If the prompt has no placeholder, Claude Code appends ARGUMENTS: … at the end.
  • For a literal $ (e.g. a price), write \$.
Migrate component $0 from $1 to $2, keeping public props unchanged.
# call: /migrate-component SearchBar JavaScript TypeScript

Run shell before sending the prompt

The !`command` syntax runs a shell command before the content reaches Claude and replaces it with the output. The model receives real data instead of having to go find it, saving a few tool calls:

---
description: Summarise the current PR for reviewers
allowed-tools: Bash(gh *)
---
- Diff: !`gh pr diff`
- Changed files: !`gh pr diff --name-only`

Summarise the PR: purpose, main changes, risks, what reviewers should look at.

Three things to remember:

  • A failing command (non-zero exit code) cancels the whole slash command. If failure is acceptable, add || true.
  • Commands still go through permission rules: denied means cancelled; needing approval also cancels, unless pre-allowed in allowed-tools.
  • Admins can disable this feature entirely with "disableSkillShellExecution": true in settings.

5 commands worth creating now

  1. /review: take git diff --staged and review it against the team checklist (security, naming, tests).
  2. /fix-issue: as above, read issue → fix → test → commit.
  3. /pr-summary: summarise the PR to paste into the description.
  4. /changelog: take git log since the last tag and write a changelog in the repo's format.
  5. /explain: explain a module to a newcomer, with a diagram of the main call flow.

Risks and caveats

  • Overly broad allowed-tools: Bash(*) in a shared committed command opens the door to any shell command. Keep it as narrow as possible, e.g. Bash(gh pr diff *).
  • Untrusted data: issue/PR content written by outsiders may contain prompt injection. Commands automating over that data shouldn't carry broad write permissions.
  • Prompt bloat: gh pr diff on a big PR can take tens of thousands of tokens. Cap it with | head -n 2000 or take only the file list.
  • Name clashes with skills: as you migrate to skills, delete the old command files to avoid confusion about which one runs.

How to apply it

  • Dev: The third time you type the same prompt, turn it into a file in .claude/commands/. Start with 2–3 commands, not a whole set at once.
  • Tech Lead: Commit standard commands (review, fix-issue, changelog) to the repo so the whole team shares one process. Review command files like code, especially the allowed-tools line.
  • PM: /pr-summary and /changelog give you consistent release notes without reading diffs.

Sources & references

  1. Slash commands / Skills — Claude Code Docs