Key Takeaway
Claude Code slash commands are reusable prompt templates saved as Markdown files in .claude/commands/, where each filename becomes a command you invoke with a slash. They capture a prompt you type often, accept arguments, and can run shell commands, so a repeatable workflow becomes one keystroke instead of a paragraph you retype.
Every developer builds up a set of prompts they retype constantly: review this diff against our checklist, write a conventional commit for the staged changes, scaffold a new API route the way we do it here. Retyping them wastes time and, worse, they drift, because the version you type on Friday is not the one from Monday. Slash commands fix that by turning a prompt into a saved, versioned file.
This guide covers what slash commands are, how to write one with arguments and tool permissions, how they differ from skills, and where they fit against the rest of Claude Code's customization surface. If you have ever pasted the same instructions twice, this is the feature that pays you back.
What a slash command is
A custom slash command is a Markdown file whose contents are a prompt. Drop a review.md file into .claude/commands/ and you can invoke it as slash-review; the filename is the command name. Project commands live in the repo and ship with the code, while personal commands live under your home directory and follow you across projects.
The body is just the prompt Claude runs when you invoke the command, but a few pieces of syntax make it dynamic:
- The ARGUMENTS placeholder captures everything you type after the command name, and positional placeholders capture individual arguments, so a review command can pass a ticket number into the prompt.
- A line beginning with an exclamation mark runs a shell command and injects its output, so a command can include the live git diff without you pasting it.
- An at-sign reference pulls a file's contents into the prompt, handy for pointing the command at a spec or a checklist that lives in the repo.
Write a command with arguments and scope
Optional YAML frontmatter configures the command. The most useful fields are description, which shows up when you browse commands; argument-hint, which documents the expected arguments; allowed-tools, which limits what the command may do; and model, which can pin a cheaper or stronger model for that specific task.
A review command that takes a ticket number and is allowed to read the diff looks like this:
---
description: Review the current diff against our checklist
argument-hint: [ticket-number]
allowed-tools: Bash(git diff:*), Read, Grep
---
Review the staged diff for ticket $ARGUMENTS.
Here is the current diff:
!git diff --staged
Check error handling, tests, and naming. Report each
issue as file:line plus a one-line fix, then end with a
clear pass or fail verdict.Use allowed-tools to scope a command to exactly what it needs. A review command that can read and grep but cannot write files or run arbitrary shell commands is safe to run on autopilot, and the tighter scope also stops Claude from wandering off the task into unrelated edits.
Slash commands versus skills
Slash commands and skills look similar, since both are Markdown with frontmatter, but they trigger in opposite ways, and choosing the wrong one is a common mistake.
- A slash command is invoked explicitly by you. It runs when, and only when, you type the slash, which makes it right for deliberate, on-demand routines.
- A skill is invoked by the model. Claude reads skill descriptions and decides on its own when a skill is relevant, which suits knowledge it should reach for automatically.
- Reach for a slash command when you want a button you press; reach for a skill when you want a capability the agent applies without being told.
- They compose. A slash command can walk through a procedure that itself relies on a skill, so the two are complementary rather than competing.
Namespacing and built-in commands
Claude Code ships with built-in commands you already rely on: slash-clear to reset context, slash-compact to summarize it, slash-init to bootstrap a CLAUDE.md, and slash-agents to manage subagents. Your custom commands live alongside them without collision, and you can organize your own into folders.
Subdirectories under .claude/commands/ become namespaces, so a file at .claude/commands/git/commit.md is invoked as a namespaced command. This keeps a growing library legible once you have more than a handful, grouping related routines the way you would group modules in code.
A command that runs shell commands through the exclamation-mark syntax executes them whenever the command is invoked, so treat those lines with the same caution as a hook. Keep destructive operations out of shared slash commands, and prefer read-only commands like git diff or git status over anything that mutates state.
Build a command library that lasts
Slash commands earn their keep when the team shares them, so treat the .claude/commands/ folder as part of the codebase, not as personal scratch.
- Commit project commands so every teammate and every CI run gets the same routine, and review changes to them the way you review code.
- Keep each command focused on one job with a clear description, because a vague command is as hard to trust as a vague function name.
- Promote a prompt to a command the second time you type it; the first repeat is the signal that it is worth saving.
Slash commands are the simplest customization Claude Code offers and often the highest return: no code, just a saved prompt that stops drifting and starts being shareable. Look at the instructions you typed today, pick the one you will type again tomorrow, and save it as a command. You will have built a small, versioned automation library before you notice.

