How to create custom slash commands in Claude Code using CLAUDE.md and the .claude/commands/ directory. Covers command syntax, arguments, template variables, and real-world examples.
Custom slash commands let you create project-specific or personal shortcuts in Claude Code. Instead of typing long prompts repeatedly, you define them once as a Markdown file and invoke them with /command-name.
# Project command (shared with team via git):
mkdir -p .claude/commands
cat > .claude/commands/review-pr.md << 'EOF'
Review the staged changes for this PR.
Check for:
- Logic errors and edge cases
- Missing error handling
- Security issues (injection, auth bypass, secrets in code)
- Test coverage for new code paths
- Naming consistency with the existing codebase
Output: bullet list of issues (if any), then a one-line verdict.
EOF
# Now use it in Claude Code:
# /review-pr
| Type | Location | Scope | Version controlled |
|---|---|---|---|
| Project command | .claude/commands/ (project root) | This project only | Yes (commit to git) |
| User command | ~/.claude/commands/ | All your projects | No (personal) |
# .claude/commands/explain.md
Explain the following code in plain English, targeting a developer
who is new to this codebase:
$ARGUMENTS
Focus on: what it does, why it exists, and any non-obvious decisions.
# Usage: /explain path/to/file.py
# Or: /explain "the retry logic in src/api.ts around line 140"
# .claude/commands/commit-msg.md
Write a concise git commit message for the staged changes below.
Format: imperative mood, under 72 chars, no period at end.
Only output the message — no explanation, no quotes.
!git diff --staged
# This command runs git diff --staged and injects the output
# Usage: /commit-msg → Claude writes the commit message based on your actual staged diff
# .claude/commands/test-this.md
Write unit tests for the function or class described below.
Use the project's testing framework (check package.json / pytest.ini).
Follow the pattern in existing test files.
$ARGUMENTS
# .claude/commands/security-check.md
Review the following for OWASP Top 10 vulnerabilities.
Pay special attention to: SQL injection, XSS, auth bypass, secrets in code.
!git diff HEAD~1
Current branch: !git branch --show-current
# .claude/commands/changelog.md
Generate a changelog entry for the changes since the last tag.
!git log $(git describe --tags --abbrev=0)..HEAD --oneline
Format as Keep a Changelog (https://keepachangelog.com):
## [Unreleased]
### Added / Changed / Fixed / Deprecated / Removed / Security
# Use subdirectories to namespace commands:
.claude/commands/
db/
migrate.md → /db:migrate
seed.md → /db:seed
rollback.md → /db:rollback
review/
security.md → /review:security
perf.md → /review:perf
api.md → /review:api
| Tip | Why |
|---|---|
Use !git diff --staged in commit/review commands | Grounds the prompt in actual code, not description |
| Specify output format explicitly | Prevents verbose prose when you want a list or single line |
| Add project context via CLAUDE.md, not per-command | Keeps commands short; CLAUDE.md already loaded in session |
| Commit project commands to git | Team shares the same shortcuts; onboarding gets /review-pr on day 1 |
| Keep user commands for personal taste | ~/.claude/commands/ for formatting preferences, personal workflows |
# CLAUDE.md sets persistent context:
# - Language: TypeScript strict mode
# - Tests: Jest, always run npm test before declaring done
# - PR reviews: check for missing types, any escape hatches
# Commands use that context automatically:
# /review-pr → Claude already knows your conventions from CLAUDE.md
# /test-this → Claude picks Jest patterns from CLAUDE.md
# This means your commands stay short — no need to repeat
# "use TypeScript", "use Jest" in every command file.
For a full CLAUDE.md reference, see claude-code-memory-guide. For the complete list of built-in slash commands, see claude-code-slash-commands.