PROMPT TO PRODUCTION
Chapter 14 of 19 · 13 min read

Chapter 14: Skills and Slash Commands

Learning Objectives

By the end of this chapter, you will be able to:

  • Create custom slash commands that automate repetitive workflows
  • Use parameterized commands with $ARGUMENTS for flexible inputs
  • Choose from the most useful built-in commands
  • Understand the difference between slash commands and skills
  • Share commands with your team through version control
  • Know when a command is worth creating and when it is not

Quick Start (5 Minutes)

Create a Custom Slash Command That Generates a PR Description

Step 1: Create the commands directory (5 seconds)

mkdir -p .claude/commands

Step 2: Create the command file (60 seconds)

Create .claude/commands/pr-describe.md with this content:

Analyze the current branch's changes and generate a pull request description.

Compare against the base branch and produce:

1. **Title**: A concise PR title (under 70 characters)
2. **Summary**: 2-3 bullet points describing what changed and why
3. **Test plan**: How to verify these changes work correctly
4. **Files changed**: List of modified files grouped by purpose

Look at the git diff and recent commit messages to understand the intent of the changes.

Step 3: Use your command (5 seconds)

In Claude Code, type:

/pr-describe

What happens:

You: /pr-describe

Claude reads the command file, then:
- Runs git diff against the base branch
- Reads recent commit messages
- Analyzes the changed files
- Generates a structured PR description

Output:
## Title: Add rate limiting to authentication endpoints

## Summary
- Added express-rate-limit middleware to login and register routes
- Configured 5 attempts per 15-minute window per IP
- Added 429 response handler with retry-after header

## Test plan
- Verify login works normally under the limit
- Confirm 429 response after 5 rapid attempts
- Check that rate limit resets after 15 minutes

## Files changed
- src/middleware/rateLimit.js (new - rate limit configuration)
- src/routes/auth.js (modified - applied middleware)
- tests/auth.test.js (modified - added rate limit tests)

You just turned a 5-minute manual task into a 5-second command. Every time you open a PR, type /pr-describe instead of writing the description from scratch.


Try This Now

Create a second command. Put this in .claude/commands/review.md:

Review this code for issues.

Check for:
- Security vulnerabilities (injection, XSS, auth issues)
- Performance problems (N+1 queries, unnecessary computation)
- Code quality (naming, structure, DRY violations)
- Missing error handling

Provide specific feedback with file names, line numbers, and severity (Critical / Warning / Suggestion).

Now type /review in any conversation. You get a consistent, thorough code review every time without retyping the prompt.


Core Concepts (15 Minutes)

What Are Slash Commands?

Slash commands are custom shortcuts stored as markdown files. When you type /command-name in Claude Code, it reads the corresponding .claude/commands/command-name.md file and uses its content as the prompt. The file name (minus .md) becomes the command name.

.claude/commands/review.md     -> /review
.claude/commands/test.md       -> /test
.claude/commands/pr-describe.md -> /pr-describe

Think of them as saved prompts that you can invoke with a few keystrokes instead of retyping paragraphs of instructions every time.

Where Commands Live

Commands are stored in your project’s .claude/commands/ directory:

your-project/
β”œβ”€β”€ .claude/
β”‚   β”œβ”€β”€ commands/
β”‚   β”‚   β”œβ”€β”€ review.md        # /review
β”‚   β”‚   β”œβ”€β”€ test.md          # /test
β”‚   β”‚   β”œβ”€β”€ pr-describe.md   # /pr-describe
β”‚   β”‚   └── explain.md       # /explain
β”‚   └── settings.json
β”œβ”€β”€ src/
└── package.json

Because commands live in your project directory, they are version-controlled with your code. Your entire team gets the same commands when they pull the repository.

Parameterized Commands with $ARGUMENTS

Commands become far more powerful when they accept arguments. Use $ARGUMENTS as a placeholder in your command file – whatever the user types after the command name gets substituted in.

File: .claude/commands/scaffold.md

Create a new $ARGUMENTS with all required boilerplate.

Follow the project's existing patterns for:
- File structure and naming conventions
- TypeScript types and interfaces
- Unit test file with happy path and edge cases
- Export from the nearest index file

Look at similar existing code in the project to match the style.

Usage:

/scaffold React component called UserProfile
/scaffold API endpoint for product search
/scaffold database migration adding an orders table

The text after /scaffold replaces $ARGUMENTS in the prompt. One command handles many different scaffolding tasks because the argument provides the specifics.

Another example: .claude/commands/explain.md

Explain $ARGUMENTS in simple terms.

Break down:
- What it does (in plain English)
- How it works (step by step)
- Why it is structured this way
- Key concepts a junior developer should understand

Use analogies where helpful.

Usage:

/explain the authentication middleware
/explain the caching strategy in src/services/cache.js
/explain how the WebSocket connection is managed

The 7 Most Useful Built-In and Custom Commands

You do not need dozens of commands. Most developers settle on 5-7 that they actually use. Here are the ones that deliver the most value:

1. /review – Code Review

Review this code for quality, security, performance, and best practices.
Provide specific feedback with file names, line numbers, and severity levels.
Format as: Critical issues first, then warnings, then suggestions.

2. /test – Test Generation

Generate comprehensive tests for the current file.

Cover:
- Happy path (normal usage)
- Edge cases (empty inputs, boundaries, nulls)
- Error cases (invalid inputs, exceptions)

Use the project's test framework. Aim for >80% coverage.
Run the tests and report results.

3. /explain – Code Explanation

Explain $ARGUMENTS in simple terms.
Break down what it does, how it works, and why it is structured this way.
Use analogies. Assume the reader is learning this concept for the first time.

4. /fix – Fix All Issues

Fix all linting errors, type errors, and code style issues in the current file.
After fixing, run the linter and tests to verify everything passes.
Summarize what was fixed.

5. /pr-describe – Pull Request Description

Analyze the current branch's changes against the base branch.
Generate a PR title, summary bullets, test plan, and file list.
Use the git diff and commit messages to understand intent.

6. /docs – Generate Documentation

Generate documentation for $ARGUMENTS.
Include: purpose, parameters, return values, usage examples, and edge cases.
Follow the project's existing documentation style.

7. /refactor – Safe Refactoring

Refactor $ARGUMENTS for better quality while maintaining functionality.
- Extract repeated code into functions
- Improve variable and function names
- Simplify complex logic
- Remove dead code
Run tests after each change to ensure nothing breaks.

Creating Commands: The Process

Step 1: Identify a task you perform 3+ times per week that takes more than a sentence to describe.

Step 2: Write the prompt you would normally type out, and save it as .claude/commands/name.md.

Step 3: Test the command on a real file in your project. Refine the prompt based on the output.

Step 4: Use the command for a week. If you stop using it, delete it. If you keep reaching for it, share it with your team.

The decision rule: Only create a command if it saves you 2+ minutes per use and you use it 3+ times per week. A library of 5 commands you use daily beats 50 commands you forget exist.

Commands vs.Β Skills

Slash commands are simple prompt expansion. The .md file contains text that becomes the prompt. No logic, no state, no special capabilities beyond what Claude Code already offers.

Skills are more powerful reusable workflows that Claude Code can invoke programmatically. Skills have access to all Claude Code tools, can maintain state, and can be shared or installed. When you invoke a skill (via the Skill tool), Claude Code runs the skill’s logic in a structured way.

For most developers, slash commands cover 95% of automation needs. You will naturally graduate to skills when you find yourself wanting conditional logic, multi-stage workflows, or shared tooling that goes beyond a single prompt.

Sharing Commands with Your Team

Because commands live in .claude/commands/, they are automatically shared through version control:

# Add commands to your repo
git add .claude/commands/
git commit -m "Add team slash commands for review, test, and PR workflows"
git push

Every team member who pulls the repo gets the same commands. This standardizes workflows across your team – everyone’s /review checks the same criteria, everyone’s /test follows the same coverage requirements.

Tip: Add a brief comment at the top of each command file describing its purpose:

<!-- Purpose: Generate PR description from current branch changes -->
<!-- Usage: /pr-describe -->
<!-- Last updated: 2025-03-01 -->

Analyze the current branch's changes and generate a pull request description.
...

This helps teammates understand what each command does without running it.


Deep Dive (Optional)

Advanced Command Patterns

Multi-Step Workflow Commands

Commands can orchestrate complex sequences:

File: .claude/commands/ship.md

Prepare this feature for shipping.

Execute these steps in order, stopping at any failure:

1. Run the full test suite
2. Run the linter
3. Review the code for security issues
4. Generate or update documentation for changed files
5. Create a git commit with a descriptive message
6. Generate a PR description

Report the result of each step. If any step fails, stop and explain what needs fixing.

Conditional Logic Commands

Commands can describe conditional behavior and Claude will follow the logic:

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

Generate tests appropriate for the current file.

Analyze the file type and adapt:
- React component -> Component tests (render, props, events, accessibility)
- API endpoint -> Integration tests (requests, responses, auth, validation)
- Utility function -> Unit tests (inputs, outputs, edge cases)
- Database model -> Model tests (CRUD, validations, relationships)

Use the project's test framework and follow existing test patterns.

Commands That Launch Agents

Commands can trigger agent-based workflows:

File: .claude/commands/audit.md

Run a comprehensive codebase audit.

Launch parallel agents to analyze:
1. Security vulnerabilities (focus on auth, injection, data exposure)
2. Performance bottlenecks (focus on queries, caching, algorithms)
3. Test coverage gaps (focus on critical paths)

Synthesize results into a single report, prioritized by severity.
Save the report to docs/audit-report.md.

Command Organization for Larger Teams

As your team grows, organize commands by category:

.claude/commands/
β”œβ”€β”€ review.md           # Code review
β”œβ”€β”€ test.md             # Test generation
β”œβ”€β”€ pr-describe.md      # PR description
β”œβ”€β”€ explain.md          # Code explanation
β”œβ”€β”€ fix.md              # Fix issues
β”œβ”€β”€ scaffold.md         # Scaffold new code ($ARGUMENTS)
└── audit.md            # Comprehensive audit

Keep the list short. If your commands directory has more than 12 files, you probably have commands nobody uses. Audit periodically and delete the ones that are not earning their keep.

When Things Go Wrong

Command file not found:

Symptoms: You type /my-command and Claude does not recognize it.

Fix: Verify the file exists at .claude/commands/my-command.md (not .claude/command/ or commands/my-command.txt). The directory must be exactly .claude/commands/ and the file must have a .md extension. Also check that you are in the correct project directory – commands are project-specific.

$ARGUMENTS not passed correctly:

Symptoms: You type /scaffold React component but the command prompt still contains the literal text $ARGUMENTS or ignores your input.

Fix: Ensure your command file uses $ARGUMENTS (all caps, with the dollar sign) as the placeholder. Everything the user types after the command name is substituted in. If you need the arguments in multiple places in the prompt, use $ARGUMENTS each time – it gets replaced everywhere it appears.

Example problem:

<!-- Wrong: using {arguments} or $args -->
Create a new {arguments} with boilerplate.

<!-- Right: using $ARGUMENTS -->
Create a new $ARGUMENTS with boilerplate.

Command does more than expected:

Symptoms: Your /fix command starts refactoring code, adding features, or making changes beyond what you intended.

Fix: Add explicit boundaries to your command prompt. Instead of β€œfix all issues in the code,” write β€œfix only linting errors and type errors. Do not refactor, rename, or restructure anything. Do not add new functionality.” Be explicit about what the command should NOT do, not just what it should do.

Command produces inconsistent results:

Symptoms: The same command gives very different output quality depending on context.

Fix: Add more structure to your prompt. Instead of β€œreview this code,” specify exactly what to check, what format to use, and what severity levels to assign. The more specific the prompt, the more consistent the output. Include an example of the expected output format if consistency matters.


Chapter Checkpoint

You should now be able to:

  • Create a custom slash command by writing a .md file in .claude/commands/
  • Use $ARGUMENTS to make commands flexible and reusable
  • Name the 5-7 most commonly useful commands and what they do
  • Explain the difference between slash commands (prompt expansion) and skills (programmable workflows)
  • Share commands with your team through version control

Competency checklist:


Try This Now

Exercise 1: Build Your Starter Command Kit

Goal: Create 3 commands tailored to your actual daily workflow.

  1. Think of the 3 tasks you do most often that require typing more than one sentence of instructions to Claude
  2. Create a .claude/commands/ file for each one
  3. Test each command on a real file in your project
  4. Refine the prompts based on the output – add specifics where the results were too vague, add constraints where the results went too far

What to look for: After one week, check which commands you actually used. Keep those, delete the rest, and consider what new command would help most.

Exercise 2: Parameterized Command

Goal: Create a flexible command that handles different inputs through $ARGUMENTS.

  1. Create .claude/commands/investigate.md:
Investigate $ARGUMENTS in this codebase.

Report:
- How it is implemented (key files and functions)
- How it is used (callers and dependents)
- Any issues or risks (bugs, security, performance)
- Suggested improvements

Be specific with file names and line numbers.
  1. Test it with different arguments:

    /investigate error handling
    /investigate the database connection pool
    /investigate how environment variables are loaded
  2. Notice how the same command adapts to completely different investigations based on the argument

What to look for: The $ARGUMENTS pattern turns one command into a flexible tool. If you find yourself creating multiple similar commands that differ only in their subject, consolidate them into one parameterized command.