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
$ARGUMENTSfor 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/commandsStep 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 pushEvery 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
.mdfile in.claude/commands/ - Use
$ARGUMENTSto 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.
- Think of the 3 tasks you do most often that require typing more than one sentence of instructions to Claude
- Create a
.claude/commands/file for each one - Test each command on a real file in your project
- 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.
- 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.Test it with different arguments:
/investigate error handling /investigate the database connection pool /investigate how environment variables are loadedNotice 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.
PROMPT TO PRODUCTION