Claude Academy
intermediate15 min

Custom Slash Commands: Build Your Own

Learning Objectives

  • Create custom slash commands with .claude/commands/
  • Use the $ARGUMENTS placeholder for dynamic commands
  • Configure command frontmatter (tools, description, hints)
  • Set up project and global command locations

Why Custom Commands?

Slash commands are Claude Code's macro system. Instead of typing the same complex instructions repeatedly, you package them as a command and invoke them with a single /command-name.

Some things you might ask Claude regularly:

  • "Fix the issue described in GitHub issue #X"
  • "Review the current diff for security issues"
  • "Generate a migration for this schema change"
  • "Run the deploy checklist"

Each of these can become a slash command you invoke in one word.

Creating Your First Command

Custom commands are Markdown files in .claude/commands/. The filename (minus .md) becomes the command name.

Step 1: Create the Directory

mkdir -p .claude/commands

Step 2: Create a Command File

Create .claude/commands/fix-issue.md:

---

description: "Fix a GitHub issue by number"

argument-hint: "issue-number"


Look up GitHub issue #$ARGUMENTS in this repository.

1. Read the issue title and description

2. Understand the reported problem

3. Find the relevant files in our codebase

4. Implement a fix that addresses the issue

5. Write tests for the fix

6. Create a commit with a message referencing the issue: "fix: description (closes #$ARGUMENTS)"

Step 3: Use It

/fix-issue 42

The $ARGUMENTS placeholder is replaced with 42, so Claude sees:

Look up GitHub issue #42 in this repository.

1. Read the issue title and description

2. Understand the reported problem

...

That's it. A reusable workflow in a markdown file.

Command Frontmatter

The YAML frontmatter at the top of a command file configures its behavior:

description

Shown when users type /help or browse available commands:

---

description: "Review the current branch for security vulnerabilities"

---

argument-hint

Describes what the argument should be — shown as a hint in the UI:

---

argument-hint: "issue-number"

---

allowed-tools

Restricts which tools the command can use:

---

allowed-tools: ["Read", "Bash(git *)", "Bash(pnpm test)"]

---

This is useful for creating safe commands that can't accidentally modify files or run dangerous operations.

Example Commands

Code Review

.claude/commands/review.md:
---

description: "Review the current branch diff for issues"


Review all changes on the current branch compared to main.

Check for:

1. Security issues (SQL injection, XSS, auth bypass, data exposure)

2. Performance problems (N+1 queries, missing indexes, unnecessary loops)

3. Error handling gaps (uncaught errors, missing validation)

4. Code style violations (check CLAUDE.md conventions)

5. Missing or inadequate tests

For each issue found, provide:

  • File and line number
  • Severity (critical / warning / suggestion)
  • Description of the issue
  • Recommended fix

If no issues are found, say so explicitly.

Usage: /review

Test Generation

.claude/commands/test.md:
---

description: "Generate tests for a file"

argument-hint: "file-path"


Generate comprehensive tests for $ARGUMENTS.

1. Read the file and understand what it does

2. Identify all public functions and methods

3. Write tests covering:

- Happy path (normal usage)

- Edge cases (empty inputs, boundary values)

- Error cases (invalid inputs, failures)

- If the file interacts with a database, test with the test DB helper

Follow our testing conventions from CLAUDE.md.

Place the test file next to the source file with .test.ts extension.

Usage: /test src/services/order-service.ts

Quick Explain

.claude/commands/explain.md:
---

description: "Explain a file or function in plain language"

argument-hint: "file-path or function-name"

allowed-tools: ["Read"]


Explain $ARGUMENTS in plain language.

  • What does it do?
  • Why does it exist?
  • How does it fit into the broader system?
  • Any non-obvious behavior or gotchas?

Keep the explanation under 200 words. Target audience: a developer

who is new to this codebase.

Usage: /explain src/lib/hmac.ts

Dependency Check

.claude/commands/deps.md:
---

description: "Check for outdated or vulnerable dependencies"

allowed-tools: ["Read", "Bash(pnpm )", "Bash(npm audit )"]


Check the project's dependency health:

1. Run pnpm outdated to find outdated packages

2. Run pnpm audit to find security vulnerabilities

3. Read package.json for any dependencies that should be replaced

Report:

  • Critical vulnerabilities (must fix now)
  • Outdated major versions (plan to update)
  • Suggestions for replacements (deprecated packages)

Usage: /deps

Two Command Locations

Project Commands: .claude/commands/

Specific to this project. Committed to git. Available to all team members.

.claude/commands/

├── fix-issue.md

├── review.md

├── test.md

├── deploy.md

└── migrate.md

Global Commands: ~/.claude/commands/

Available in every project. Personal to you.

~/.claude/commands/

├── explain.md

├── summarize.md

├── standup.md

└── review-security.md

Put project-specific commands (deploy, migrate, fix-issue) in the project directory. Put personal workflow commands (explain, summarize) in the global directory.

Organizing Commands

As your command library grows, organize with subdirectories:

.claude/commands/

├── git/

│ ├── pr.md

│ ├── changelog.md

│ └── release.md

├── dev/

│ ├── test.md

│ ├── lint.md

│ └── migrate.md

└── review/

├── security.md

├── performance.md

└── accessibility.md

Access with: /git/pr, /dev/test, /review/security

Key Takeaway

Custom slash commands are markdown files in .claude/commands/ (project) or ~/.claude/commands/ (global). Use $ARGUMENTS for dynamic input, frontmatter for configuration (description, argument-hint, allowed-tools). Commands turn multi-step workflows into single-word invocations. Start with 3-5 commands for your most common workflows — code review, test generation, and issue fixing are great starting points — and grow your library as you identify repetitive patterns.