# Create a Custom Slash Command in Claude Code

> Drop a Markdown file in .claude/commands/ and the filename becomes the command. Note $0 is the first positional argument, and skills are now preferred.

- Canonical: https://guides-ai.pages.dev/guides/create-claude-code-slash-command/
- Plate 03.02 · Topic: Claude Code commands (https://guides-ai.pages.dev/topics/commands/)
- Published: 10 Jun 2026 · Updated: 06 Sept 2026 · 3 min read
- Source site: guides-ai — https://guides-ai.pages.dev/

A slash command is one Markdown file, and the filename becomes the command name. Worth knowing
before you start: **custom commands have been merged into skills.** `.claude/commands/deploy.md`
and `.claude/skills/deploy/SKILL.md` both create `/deploy` and behave the same way; existing
command files keep working, but skills are the recommended form because they can carry
supporting files.

## 1. Create the folder

```powershell
mkdir .claude\commands
```

What it does: creates the project-level command folder, shared with everyone who clones the
repo. Use `~/.claude/commands` for commands that are yours in every project.

## 2. Add the file

`.claude\commands\review.md` becomes `/review`:

```markdown
Review the current git diff for correctness bugs and risky changes.
Be concise. Skip style nitpicks. $ARGUMENTS
```

What it does: the body is the prompt, and `$ARGUMENTS` is replaced by everything you type after
the command.

## 3. Take positional arguments

Numbered placeholders start at **`$0`** — a genuine trap if you expect `$1` first:

```markdown
Migrate the $0 component from $1 to $2.
```

What it does: with `/migrate-component Button JavaScript TypeScript`, `$0` becomes `Button`,
`$1` becomes `JavaScript`, `$2` becomes `TypeScript`. `$ARGUMENTS[0]` is an equivalent syntax.

## 4. Add frontmatter

```markdown
---
description: Summarize uncommitted changes
allowed-tools: Bash(git *)
argument-hint: [path]
---

## Current changes

!`git diff HEAD`

Summarize the changes above and flag any risks.
```

What it does: `description` shows in the picker, `allowed-tools` pre-approves tools without a
permission prompt, `argument-hint` appears in autocomplete, and `` !`command` `` runs the shell
command first and substitutes its output — so Claude receives the real diff, not an instruction
to go get it. A non-zero exit aborts the invocation, so append `|| true` where failure is fine.

## Verify it worked

Type `/` and check the command appears with your description. Run it with an argument and read
the first line Claude echoes back: if `$ARGUMENTS` is still literal text, the placeholder is
misspelled or wrapped in a code fence.

Keep each command to one job. Commands in nested project directories become available when
Claude works in that subdirectory, and a name collision resolves to a directory-qualified form
like `/apps/web:deploy`. Every [slash command](/glossary/#slash-command) you save is a workflow
you stop retyping.

Next: [skills and plugins](/guides/claude-code-skills-and-plugins/), the richer form of the same
idea, or [subagents](/guides/claude-code-subagents/) when the job deserves its own context
window.

Source: [Claude Code slash commands](https://code.claude.com/docs/en/slash-commands).
