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?
| Location | Creates | Use when |
|---|---|---|
.claude/commands/review.md | /review | A shared team command, committed to the repo |
.claude/commands/frontend/component.md | /frontend:component | Grouping commands by subfolder (namespace) |
.claude/skills/review/SKILL.md | /review | You 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
| Field | Meaning |
|---|---|
description | A short description shown in the menu that also helps Claude know when to use it. Put the key idea first. |
argument-hint | Parameter hint shown in autocomplete, e.g. [issue-number]. |
allowed-tools | Tools usable without asking permission, only during this command's turn. |
model | Model 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": truein settings.
5 commands worth creating now
- /review: take
git diff --stagedand review it against the team checklist (security, naming, tests). - /fix-issue: as above, read issue → fix → test → commit.
- /pr-summary: summarise the PR to paste into the description.
- /changelog: take
git logsince the last tag and write a changelog in the repo's format. - /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 diffon a big PR can take tens of thousands of tokens. Cap it with| head -n 2000or 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-toolsline. - PM:
/pr-summaryand/changeloggive you consistent release notes without reading diffs.
Sources & references
- Slash commands / Skills — Claude Code Docs