Home AI/ML Mastering Custom Commands in Claude Code: The Definitive Guide to Automating Your Development Workflow

Mastering Custom Commands in Claude Code: The Definitive Guide to Automating Your Development Workflow

Last updated: May 27, 2026
k
Published April 4, 2026 · Updated May 27, 2026 · 42 min read

Summary

What this post covers: A definitive guide to Claude Code custom commands, the Markdown files in .claude/commands/ that convert multi-step workflows into one-line slash commands, including anatomy, best practices, ten ready-to-use commands, advanced techniques, and the organization of a team library.

Key insights:

  • Custom commands require zero configuration: any .md file placed in .claude/commands/ or ~/.claude/commands/ becomes a slash command immediately, with no registration step or build process.
  • The project-versus-user distinction is the most important design decision: project commands are committed to git and standardize team workflows (deploy, review, scaffold), while user commands remain personal and codify individual preferences.
  • The most substantial productivity gains derive from the $ARGUMENTS placeholder combined with explicit constraints sections. Vague commands produce vague behaviour, so commands should read as detailed briefings containing checklists and failure-handling rules.
  • Custom commands are most valuable as encoded tribal knowledge: the deployment runbook held in one engineer’s mind becomes an executable file that the entire team uses, ensuring that deployments and reviews follow the same process each time.
  • Begin with three commands: the most frequent task, the most disliked task, and the team’s most significant pain point. Any instruction repeated three times should subsequently be converted into a new command.

Main topics: What Are Custom Commands?, Anatomy of a Command File, Best Practices for Writing Effective Commands, Practical Command Examples (10 Ready-to-Use Commands), Advanced Techniques, Project Commands and User Commands, Integration with CLAUDE.md, Organizing Commands for Large Projects, Common Mistakes and How to Avoid Them, Real-World Command Libraries by Technology Stack, Conclusion, References.

A developer at a mid-sized startup recently described an instructive change in routine: a workflow that previously required 45 minutes each morning (setting up the development environment, running tests, reviewing PRs, and scaffolding new features) now requires under 5 minutes. The mechanism was not a new DevOps pipeline or a new CI/CD tool, but seven carefully constructed custom commands in Claude Code, Anthropic’s AI-powered CLI for software development.

Most users of Claude Code are familiar with its ability to write code, debug issues, and answer questions about a codebase. A less prominent feature, however, transforms Claude Code from a useful assistant into an automated development partner: custom commands. These are Markdown files that convert complex, multi-step workflows into one-line slash commands available at any time.

Custom commands can be understood as macros at a higher level of abstraction. Rather than recording keystrokes, the developer writes natural-language instructions that Claude Code follows with full access to the codebase, the terminal, and project tools. A single command may review code for security vulnerabilities, check for style violations, and generate a summary. A separate command may scaffold an entire API endpoint with route, handler, validation, and tests within minutes.

Despite this capability, most developers exploit only the basic functionality. They may create one or two simple commands but fail to take advantage of the advanced patterns that make custom commands genuinely transformative: argument handling, conditional logic, multi-step workflows with checkpoints, and integration with project-level configuration. This guide addresses that gap. By its end, readers will have the material required to build a comprehensive command library that automates the most repetitive parts of a development workflow, together with ten complete, ready-to-use command files as a starting point.

What Are Custom Commands?

At their core, custom commands in Claude Code are Markdown files that reside in a specific directory structure. When a user types / in Claude Code, the tool scans these directories and presents every available command as a selectable option. When a command is invoked, Claude Code reads the Markdown content and treats it as its instruction set; effectively, the developer is providing Claude with a detailed prompt for a specific task, and Claude executes it with full project context.

Two Types of Commands

Claude Code recognizes commands in two locations, and understanding the distinction is important for team workflows:

Project commands reside in the project’s .claude/commands/ directory. Because they live inside the repository, they are committed to version control and shared with every team member. When a colleague clones the repository and opens Claude Code, they automatically see and can use every project command. This makes such commands appropriate for team-wide workflows such as deployment, code review, and feature scaffolding.

User commands reside in ~/.claude/commands/ within the user’s home directory. These are personal to the individual and are not shared via git. They are appropriate for productivity shortcuts, personal preferences, and workflows that are specific to a developer’s setup. Examples include a command that formats output in a preferred manner or one that interacts with internal tools used only by that individual.

Key Takeaway: Project commands (.claude/commands/) are shared with the team via git. User commands (~/.claude/commands/) are personal and remain on the individual machine. Project commands are appropriate for team workflows; user commands are appropriate for personal productivity.

Command Scope: Project vs User Commands Project Commands Shared via version control your-repo/ .claude/commands/ deploy.md → /deploy review-code.md → /review-code add-feature.md → /add-feature Committed to git Available to all team members Best for: deploy, test, scaffold User Commands Personal to your machine ~/ (home directory) .claude/commands/ my-style.md → /my-style personal-log.md → /personal-log internal-tool.md → /internal-tool Never committed to git Private to your environment Best for: preferences, personal tools

How Claude Code Discovers Commands

When Claude Code is launched in a project directory, it performs a straightforward discovery procedure. It first checks .claude/commands/ relative to the project root, then checks ~/.claude/commands/ in the user’s home directory. Every .md file found in these directories becomes an available command, with the filename (minus the extension) becoming the command name. Thus .claude/commands/deploy.md becomes /deploy, and .claude/commands/write-post.md becomes /write-post.

This discovery occurs automatically; there is no registration step, no configuration file to update, and no CLI flag to set. A Markdown file placed in the correct directory becomes instantly available as a command, and removal causes the command to disappear. The simplicity of this mechanism is the source of its power: the barrier to creating a new command is effectively zero.

Command File Structure:.md File → /command in CLI .claude/commands/deploy.md # Deploy Command Deploy to: $ARGUMENTS ## Step 1: Check tests ## Step 2: Build ## Step 3: Push to server ## Constraints:… auto-discovered no registration $ /deploy staging Naming Rule deploy.md → /deploy write-post.md → /write-post More examples review-code.md → /review-code add-feature.md → /add-feature fix-bug.md → /fix-bug greet.md → /greet Filename (kebab-case, no extension) becomes the slash command name. No configuration needed.

Anatomy of a Command File

A command file is a Markdown document, although its structure matters. The following sections examine each element, beginning with the basics and progressing to more complex patterns.

File Naming Conventions

Command files follow a simple naming scheme:

  • Use kebab-case for filenames: write-post.md, review-code.md, create-component.md
  • Always use the .md extension
  • The filename becomes the command name: deploy.md/deploy
  • Names should be short and descriptive, since they will be typed frequently

The Markdown Structure

The content of a command file is the prompt that Claude Code receives when the command is invoked. Everything written in the file becomes Claude’s instructions. The file should therefore be written as a detailed briefing to a capable developer who has not previously seen the project.

The simplest possible command file illustrates the concept:

# File: .claude/commands/greet.md

Say hello to the user and tell them the current date and time.
List the top 3 most recently modified files in the project.

When /greet is typed in Claude Code, the tool reads this file and follows the instructions. Real-world commands, however, require considerably more structure. The following section examines a properly organized command.

The $ARGUMENTS Placeholder

One of the most useful features of custom commands is the $ARGUMENTS placeholder. When a command is invoked with additional text (for example, /deploy staging or /write-tests src/utils/parser.py), everything after the command name is substituted into the $ARGUMENTS placeholder in the Markdown file.

# File: .claude/commands/explain.md

Read the file or function specified by the user: $ARGUMENTS

Provide a detailed explanation that includes:
1. What the code does at a high level
2. Key algorithms or patterns used
3. Any potential issues or improvements
4. How it fits into the broader codebase

When /explain src/auth/middleware.py is typed, Claude Code receives the full instructions with $ARGUMENTS replaced by src/auth/middleware.py. This single mechanism enables flexible commands that adapt to whatever input is provided.

Command Execution Flow: From Slash Command to Result User types /explain auth/login.py File loaded .claude/commands/ explain.md $ARGUMENTS injected “Read the file or function: auth/login.py” placeholder replaced Claude executes Reads file, explains code, reports back CLI input Markdown file Prompt assembled AI action The $ARGUMENTS Placeholder /explain auth/login.py Everything after the command name → injected as $ARGUMENTS

A Full Command File Example

The following well-structured command demonstrates all the key elements working together:

# File: .claude/commands/add-feature.md

You are a senior developer working on this project. Add a new feature
based on the following description: $ARGUMENTS

## Step 1: Understand the Request
- Parse the feature description from $ARGUMENTS
- Identify which parts of the codebase will be affected
- List the files you plan to modify or create

## Step 2: Plan the Implementation
- Outline the changes needed
- Identify any dependencies or prerequisites
- Check for existing patterns in the codebase to follow

## Step 3: Implement the Feature
- Write clean, well-documented code
- Follow existing code style and conventions in the project
- Add appropriate error handling

## Step 4: Write Tests
- Create unit tests for the new feature
- Ensure existing tests still pass by running: `npm test`

## Step 5: Summary
- List all files created or modified
- Describe the changes made
- Note any follow-up tasks or considerations

## Constraints
- Do NOT modify any configuration files without asking first
- Do NOT install new dependencies without listing them and explaining why
- Follow the project's existing code style exactly
- If $ARGUMENTS is empty, ask the user what feature they want to add

Several important patterns are present in this example: numbered steps provide Claude with a clear execution order, constraints establish boundaries on permissible actions, and the command handles the edge case in which no arguments are provided. This level of detail distinguishes a good command from an excellent one.

Tip: A command file should be treated as a detailed brief for a new team member. The more specific the description of what to do, what not to do, and what patterns to follow, the better the resulting behaviour.

Best Practices for Writing Effective Commands

After examination of numerous custom commands and observation of teams adopting them across different technology stacks, clear patterns have emerged for what makes commands reliable rather than unreliable. The distinction almost invariably reduces to the precision with which intent is communicated.

Be Specific and Explicit

Claude Code follows instructions literally. The instruction “clean up the code” will produce changes based on Claude’s best judgment. The instruction “remove unused imports, add type hints to all function signatures, and ensure all functions have docstrings following the Google style guide” produces precisely that. Specificity is not pedantry but precision.

Structure with Clear Steps

Numbered lists are particularly valuable in command files. They establish a natural execution order and make it straightforward for Claude to report progress. Each step should be a discrete, verifiable action. Rather than “set up the project,” the instruction should be decomposed into: (1) create the directory structure, (2) initialize the package manager, (3) install dependencies, (4) create the configuration file.

Include Constraints and Guardrails

This may be the single most important practice. Claude should always be informed of what not to do. Without constraints, Claude will make reasonable but potentially unwanted decisions. Explicit guardrails should be added, such as “do NOT modify the database schema,” “always create a backup before overwriting,” or “never commit directly to main.”

Specify Output Format

If the result is required in a specific format (a JSON file, a Markdown report, a formatted table in the terminal), this should be stated explicitly. Commands that end with “report what you did” tend to produce inconsistent output. Commands that end with “create a summary in the following format: [template]” produce consistent, useful results.

Include Error Handling Instructions

What should Claude do if a test fails, a file does not exist, or a build breaks? Without error-handling instructions, Claude will either stop and ask (slowing the workflow) or guess (potentially incorrectly). Explicit error handling should be included: “If the tests fail, analyse the failure, fix the issue, and re-run the tests. If they fail a second time, stop and report the errors.”

Reference Specific Files and Paths

When a command must operate on specific parts of the codebase, the targets should be referenced explicitly. Rather than “check the config file,” the instruction should be “read config/settings.py and extract the database URL.” This eliminates ambiguity and ensures that the command operates reliably as the project evolves.

Use Conditional Logic

Real workflows branch on conditions. Commands should do likewise: “If $ARGUMENTS contains ‘staging’, deploy to the staging server. If it contains ‘production’, deploy to production with additional safety checks. If no argument is provided, default to staging.”

Keep Commands Focused

A command that attempts to do everything performs no individual task well. The single-responsibility principle should be observed: one command, one job. A complex workflow should be decomposed into multiple commands that can be run in sequence. Separate /build, /test, and /deploy commands are preferable to a single monolithic /do-everything command.

Good and Bad Command Patterns

Pattern Bad Example Good Example
Instructions “Fix the bugs” “Run the test suite, identify failing tests, analyze each failure, and apply minimal fixes”
File references “Update the config” “Update config/database.yml and .env.example
Error handling (none) “If tests fail, fix and re-run. After 2 failures, stop and report.”
Output format “Tell me what changed” “List changed files as a Markdown checklist with one-line descriptions”
Constraints (none) “Do NOT modify files outside src/. Do NOT add dependencies.”
Scope One giant command for build + test + deploy + notify Separate /build, /test, /deploy, and /notify commands

 

Practical Command Examples (10 Ready-to-Use Commands)

Theory is useful, but readers may benefit from commands that can be used directly. The following ten complete, production-proven command files cover the most common development workflows. Each is ready to copy into a .claude/commands/ directory for immediate use.

The /write-post Command: Blog Publishing Workflow

This is the command that supports the blog from which this guide is published. It orchestrates the entire workflow of selecting a topic, writing a full blog post, and publishing it to WordPress, all from a single slash command.

# File: .claude/commands/write-post.md

You are a professional tech and investment blog writer.
Write and publish a blog post using the following workflow:

## Step 1: Topic Selection
- If the user provides a topic in $ARGUMENTS, use that topic.
- Otherwise, run `uv run python -m src.main select-topic` to pick
  a random topic from the configured pool.
- Show the selected topic and its category to the user.

## Step 2: Write the Blog Post
Write a high-quality, engaging blog post as clean WordPress-ready HTML5.

**Writing Style:**
- Open with a powerful hook: a surprising fact, bold question, or
  real incident
- Conversational yet professional tone
- Target: 4,000-6,000 words minimum
- Structure: Table of Contents → Introduction → 3-5 body sections
  → Conclusion → References
- No <h1> tags, no <html>/<head>/<body> wrappers

## Step 3: Save and Publish
1. Save the HTML content to `posts/{slug}.html`
2. Run the publish command:
   ```
   uv run python -m src.main publish \
     --title "<title>" --slug "<slug>" \
     --category "<category>" \
     --content-file posts/{slug}.html \
     --status publish
   ```
3. Run `uv run python -m src.main record-usage "<topic>"`
4. Report the published post URL to the user.

## Constraints
- Do NOT use external LLM APIs — you are the writer
- For investment posts, include a disclaimer
- No numbered section headings

The /review-code Command: Comprehensive Code Review

# File: .claude/commands/review-code.md

Perform a thorough code review on the following: $ARGUMENTS

If $ARGUMENTS is a file path, review that specific file.
If $ARGUMENTS is a directory, review all source files in it.
If $ARGUMENTS is empty, review all staged changes (git diff --cached).

## Review Checklist

### Security
- [ ] No hardcoded secrets, API keys, or passwords
- [ ] Input validation on all user-facing inputs
- [ ] SQL injection / XSS vulnerabilities
- [ ] Proper authentication and authorization checks

### Code Quality
- [ ] Functions are under 50 lines (flag any that exceed this)
- [ ] No code duplication (DRY principle)
- [ ] Clear variable and function names
- [ ] Proper error handling (no bare except/catch blocks)

### Performance
- [ ] No N+1 query patterns
- [ ] Efficient data structures used
- [ ] No unnecessary loops or redundant computations
- [ ] Large datasets handled with pagination or streaming

### Testing
- [ ] New code has corresponding tests
- [ ] Edge cases are covered
- [ ] Test names clearly describe what they test

## Output Format
For each issue found, report:
1. **File and line number**
2. **Severity**: Critical / Warning / Suggestion
3. **Category**: Security / Quality / Performance / Testing
4. **Description**: What the issue is
5. **Fix**: Suggested code change

End with a summary table:
| Severity | Count |
|----------|-------|
| Critical | X     |
| Warning  | X     |
| Suggestion | X   |

## Constraints
- Do NOT modify any files — this is a review only
- If no issues are found, say so explicitly
- Be constructive, not just critical

The /create-component Command: Frontend Component Scaffolding

# File: .claude/commands/create-component.md

Create a new React component based on: $ARGUMENTS

## Step 1: Parse the Request
- Component name from $ARGUMENTS (e.g., "UserProfile" or "DataTable")
- If $ARGUMENTS includes additional description, use it for the
  component's functionality

## Step 2: Check Project Conventions
- Read the project's existing components to match the style
- Detect whether the project uses TypeScript or JavaScript
- Detect the CSS approach (CSS modules, Tailwind, styled-components)
- Check if the project uses a testing library (Jest, Vitest, etc.)

## Step 3: Create the Component
Create the following files:

1. **Component file**: `src/components/{ComponentName}/{ComponentName}.tsx`
   - Use functional component with hooks
   - Include proper TypeScript interfaces for props
   - Add JSDoc comments

2. **Test file**: `src/components/{ComponentName}/{ComponentName}.test.tsx`
   - Test rendering without errors
   - Test prop variations
   - Test user interactions if applicable

3. **Styles file**: `src/components/{ComponentName}/{ComponentName}.module.css`
   (or appropriate format for the project)

4. **Index file**: `src/components/{ComponentName}/index.ts`
   - Re-export the component as default and named export

## Step 4: Integration
- Add the component to any barrel export files if they exist
- Show a usage example in the terminal

## Constraints
- Match the EXACT coding style of existing components
- Do NOT install new packages
- If the component directory pattern differs in the project, follow
  the existing pattern instead

The /deploy Command: Deployment Workflow

# File: .claude/commands/deploy.md

Deploy the application to the specified environment: $ARGUMENTS

## Environment Detection
- If $ARGUMENTS is "staging" or "stage": deploy to staging
- If $ARGUMENTS is "production" or "prod": deploy to production
- If $ARGUMENTS is empty: default to staging

## Pre-Deployment Checks (ALL must pass)
1. Run `git status` — working directory must be clean
2. Run the full test suite — all tests must pass
3. Run the linter — no errors allowed (warnings are OK)
4. Verify the current branch:
   - Staging: any branch is fine
   - Production: must be on `main` or `master`

If ANY check fails, stop immediately and report the failure.
Do NOT proceed to deployment.

## Deployment Steps

### For Staging
1. Build the project: `npm run build` (or project equivalent)
2. Deploy: `npm run deploy:staging`
3. Run smoke tests: `npm run test:smoke -- --env=staging`
4. Report the staging URL

### For Production
1. Confirm with the user: "You are about to deploy to PRODUCTION.
   Continue? (y/n)"
2. Build: `npm run build`
3. Create a git tag: `git tag -a v{date} -m "Production deploy"`
4. Deploy: `npm run deploy:production`
5. Run smoke tests: `npm run test:smoke -- --env=production`
6. Report the production URL

## Post-Deployment
- Show the deployment summary (environment, commit SHA, timestamp)
- If smoke tests fail, immediately report and suggest rollback steps

## Constraints
- NEVER deploy to production without user confirmation
- NEVER skip the pre-deployment checks
- If this is a production deploy, ensure all staging tests passed first

The /fix-bug Command: Bug Investigation and Fix

# File: .claude/commands/fix-bug.md

Investigate and fix the following bug: $ARGUMENTS

## Step 1: Understand the Bug
- Parse the bug description from $ARGUMENTS
- If a file or line number is referenced, start there
- If an error message is provided, search the codebase for it

## Step 2: Reproduce
- Identify the conditions that trigger the bug
- Check if there is an existing test that should catch this
- If possible, write a failing test that demonstrates the bug

## Step 3: Root Cause Analysis
- Trace the code path that leads to the bug
- Identify the root cause (not just the symptom)
- Check if the same pattern exists elsewhere (similar bugs waiting
  to happen)

## Step 4: Fix
- Apply the minimal change that fixes the root cause
- Do NOT refactor unrelated code — stay focused on the bug
- Ensure the fix handles edge cases

## Step 5: Verify
- Run the failing test — it should now pass
- Run the full test suite — no regressions allowed
- If the fix touches an API, verify the API contract is maintained

## Step 6: Report
Provide a structured report:
- **Bug**: One-line description
- **Root Cause**: What was actually wrong
- **Fix**: What was changed and why
- **Files Modified**: List with brief descriptions
- **Test Coverage**: What tests were added or modified
- **Risk Assessment**: Low/Medium/High — could this fix break
  anything else?

## Constraints
- Do NOT make changes unrelated to the bug
- If the fix requires a database migration, flag it but do NOT run it
- If the bug cannot be fixed without breaking changes, stop and
  report your findings

The /refactor Command: Guided Refactoring

# File: .claude/commands/refactor.md

Refactor the specified code: $ARGUMENTS

If $ARGUMENTS is a file path, refactor that file.
If $ARGUMENTS is a description (e.g., "extract auth logic into
a service"), follow those instructions.

## Step 1: Analyze Current State
- Read the target code thoroughly
- Identify code smells: duplication, long functions, deep nesting,
  unclear naming, tight coupling
- List all functions and classes that will be affected
- Check test coverage for the target code

## Step 2: Plan the Refactoring
Present a plan BEFORE making any changes:
- What patterns will you apply (Extract Method, Move to Module, etc.)
- Which files will be created, modified, or deleted
- What is the expected impact on the public API
- Wait for user approval before proceeding

## Step 3: Execute (only after approval)
- Apply changes incrementally — one refactoring pattern at a time
- After each change, run tests to catch regressions early
- Preserve all existing behavior — this is a refactor, not a rewrite

## Step 4: Update Tests
- Adjust test imports and references as needed
- Add tests for any newly extracted functions or modules
- Run the full test suite and confirm everything passes

## Step 5: Summary
- List the refactoring patterns applied
- Show before/after metrics (function count, average length, etc.)
- Note any follow-up refactoring opportunities

## Constraints
- Do NOT change external behavior or public API
- Do NOT combine refactoring with feature changes
- Run tests after EVERY significant change
- If tests fail at any point, revert the last change and report

The /write-tests Command: Test Generation

# File: .claude/commands/write-tests.md

Write comprehensive tests for: $ARGUMENTS

$ARGUMENTS can be a file path, a function name, or a module name.

## Step 1: Analyze the Target
- Read the source code for $ARGUMENTS
- Identify all public functions, methods, and classes
- Map out the logic branches (if/else, try/catch, loops)
- Identify external dependencies that need mocking

## Step 2: Determine Testing Approach
- Detect the project's testing framework (pytest, jest, vitest, etc.)
- Match the existing test file naming convention
- Match the existing test style (describe/it, test(), class-based)

## Step 3: Write Tests
For each public function or method, write tests covering:

1. **Happy path**: Normal inputs producing expected outputs
2. **Edge cases**: Empty inputs, None/null, boundary values
3. **Error cases**: Invalid inputs, exceptions, error states
4. **Integration points**: Interactions with dependencies (mocked)

Test naming convention: `test_{function_name}_{scenario}_{expected_result}`
(or the project's existing convention if different)

## Step 4: Verify
- Run the new tests: they should all pass
- Run the full test suite: no regressions
- Check coverage if a coverage tool is configured

## Output
- Created test file path
- Number of test cases written
- Coverage summary (if available)

## Constraints
- Do NOT modify the source code being tested
- Mock external dependencies (database, APIs, file system)
- Each test must be independent — no shared mutable state
- Do NOT test private/internal functions unless critical

The /db-migration Command: Database Migration Workflow

# File: .claude/commands/db-migration.md

Create a database migration for: $ARGUMENTS

## Step 1: Understand the Change
- Parse the migration description from $ARGUMENTS
- Examples: "add email_verified column to users table",
  "create orders table with foreign key to users"

## Step 2: Detect the ORM and Migration Tool
- Check for: Alembic (Python), Prisma (Node), TypeORM, Knex,
  Django migrations, Rails ActiveRecord, or raw SQL
- Read existing migrations to understand the naming convention
  and style

## Step 3: Generate the Migration
Using the detected tool:

**For Alembic (Python/SQLAlchemy):**
```
alembic revision --autogenerate -m "$ARGUMENTS"
```
Then review and adjust the generated migration.

**For Prisma:**
Update `prisma/schema.prisma`, then run:
```
npx prisma migrate dev --name {migration_name}
```

**For Django:**
Update the model, then run:
```
python manage.py makemigrations --name {migration_name}
```

**For raw SQL:**
Create up and down migration files in the migrations directory.

## Step 4: Review the Migration
- Verify the UP migration does what was requested
- Verify the DOWN migration correctly reverses the change
- Check for:
  - Missing indexes on foreign keys
  - Missing NOT NULL constraints where appropriate
  - Missing default values
  - Data loss risks in column type changes

## Step 5: Test
- Run the migration UP
- Verify the schema change
- Run the migration DOWN
- Verify the schema is restored

## Constraints
- NEVER run migrations against production — local/dev only
- Always create both UP and DOWN migrations
- Flag any migration that could cause data loss
- If adding a NOT NULL column to an existing table, include a
  default value or a backfill step

The /api-endpoint Command: API Endpoint Scaffolding

# File: .claude/commands/api-endpoint.md

Create a new API endpoint: $ARGUMENTS

$ARGUMENTS format: "METHOD /path - description"
Examples:
- "POST /api/users - create a new user"
- "GET /api/orders/:id - get order details"
- "PUT /api/settings - update user settings"

## Step 1: Parse the Request
- Extract HTTP method, path, and description from $ARGUMENTS
- Identify path parameters (e.g., :id)
- Determine the resource name (e.g., users, orders, settings)

## Step 2: Detect the Framework
Check for: Express, FastAPI, Django REST, Flask, Gin, Fiber, etc.
Read existing routes to match the project's patterns.

## Step 3: Create the Endpoint

### Route/Handler file
- Add the route to the appropriate router file
- Create the handler function with:
  - Request validation (parse and validate input)
  - Business logic (or call to service layer)
  - Response formatting
  - Error handling with appropriate HTTP status codes

### Validation/Schema
- Create request body schema (for POST/PUT)
- Create response schema
- Add validation rules (required fields, types, formats)

### Service Layer (if the project uses one)
- Create or update the service with the business logic
- Keep the handler thin — it should only handle HTTP concerns

### Tests
Create tests for:
- Successful request (200/201)
- Validation error (400)
- Not found (404) — for endpoints with path params
- Unauthorized (401) — if auth is required
- Server error handling (500)

## Step 4: Update Documentation
- If the project has an OpenAPI/Swagger spec, update it
- If the project has API docs, add the new endpoint

## Step 5: Verify
- Start the dev server (if not running)
- Run the new tests
- Show a curl example for testing the endpoint manually

## Constraints
- Follow existing patterns EXACTLY — consistency is critical
- Include proper authentication middleware if other endpoints use it
- Use the project's error handling patterns
- Do NOT add new dependencies

The /changelog Command: Changelog Generation

# File: .claude/commands/changelog.md

Generate a changelog based on recent git history.

## Parameters
- If $ARGUMENTS contains a version tag (e.g., "v1.2.0"), generate
  the changelog since that tag
- If $ARGUMENTS contains "last-release", find the most recent tag
  and generate since then
- If $ARGUMENTS is empty, generate for the last 50 commits

## Step 1: Gather Commits
Run: `git log --oneline --no-merges {range}`
Read all commit messages in the specified range.

## Step 2: Categorize Changes
Group commits into these categories:
- **New Features**: commits mentioning "add", "feat", "new",
  "implement", "introduce"
- **Bug Fixes**: commits mentioning "fix", "bug", "resolve",
  "patch", "correct"
- **Performance**: commits mentioning "perf", "optimize", "speed",
  "cache"
- **Breaking Changes**: commits mentioning "breaking", "remove",
  "deprecate", "migrate"
- **Documentation**: commits mentioning "doc", "readme", "guide"
- **Other**: everything else

## Step 3: Generate the Changelog
Format as Markdown:

```
## [Version] - YYYY-MM-DD

### New Features
- Description of feature (commit hash)

### Bug Fixes
- Description of fix (commit hash)

### Performance
- Description of improvement (commit hash)

### Breaking Changes
- Description of breaking change (commit hash)

### Other
- Description (commit hash)
```

## Step 4: Save
- Save to `CHANGELOG.md` (append to top, keep existing content)
- Show the generated changelog in the terminal

## Constraints
- Do NOT modify commit history
- If a commit message is unclear, include it under "Other" with
  the full message
- Skip merge commits
- Include commit short hashes for reference
Tip: All ten commands above are ready to use. Copy any of them into a .claude/commands/ directory, adjust the project-specific details (test commands, directory paths, framework references), and use them immediately.

Advanced Techniques

Once the basics of writing custom commands are understood, several advanced patterns enable more capable workflows. These techniques distinguish simple automation from sophisticated development orchestration.

Chaining Commands

Although Claude Code does not provide a built-in command-chaining mechanism, the same effect can be achieved by writing a command that instructs Claude to execute the same steps as other commands. The pattern can be viewed as inlining multiple commands into a single master workflow.

# File: .claude/commands/ship-it.md

Execute the full ship-it workflow for: $ARGUMENTS

## Step 1: Code Review
Perform a thorough code review on all staged changes.
Check for security issues, code quality, and performance.
If any CRITICAL issues are found, stop and report them.

## Step 2: Write Tests
For any new or modified functions that lack test coverage,
write comprehensive tests following the project's conventions.
Run all tests and ensure they pass.

## Step 3: Generate Changelog
Categorize the changes being shipped and prepare a changelog entry.

## Step 4: Deploy
If all checks pass, deploy to staging.
Run smoke tests against staging.
Report the final status.

## If any step fails, stop immediately and report what went wrong.

Using Environment Context

Commands can instruct Claude to read environment files, configuration, and project metadata in order to make dynamic decisions. The result is that a single command can behave differently across different projects or environments.

# File: .claude/commands/setup-env.md

Set up the development environment for this project.

## Step 1: Detect the Project Type
- Check for `package.json` → Node.js project
- Check for `pyproject.toml` or `requirements.txt` → Python project
- Check for `go.mod` → Go project
- Check for `Cargo.toml` → Rust project

## Step 2: Install Dependencies
Based on the detected project type:
- **Node.js**: Run `npm install` or `yarn install` or `pnpm install`
  (check for lock files to determine which)
- **Python**: Run `uv sync` or `pip install -r requirements.txt`
- **Go**: Run `go mod download`
- **Rust**: Run `cargo build`

## Step 3: Configure Environment
- Check if `.env.example` exists but `.env` does not
- If so, copy `.env.example` to `.env` and tell the user to fill
  in the values
- Check for any other setup scripts in `scripts/` or `Makefile`

## Step 4: Verify
- Run a basic health check (test command, build, or lint)
- Report success or any issues found

Advanced Use of $ARGUMENTS

The $ARGUMENTS placeholder can convey considerably more than simple strings. Commands can be designed to parse complex argument patterns:

# File: .claude/commands/generate.md

Generate code based on the specification: $ARGUMENTS

## Argument Parsing
Parse $ARGUMENTS as: "{type} {name} [options]"

Examples:
- `/generate model User name:string email:string admin:boolean`
- `/generate controller OrdersController --crud`
- `/generate service PaymentService --with-tests --with-docs`
- `/generate middleware AuthMiddleware`

## Type handlers:

### model
- Create a database model with the specified fields
- Field format: `fieldname:type` (string, number, boolean, date)
- Generate a migration for the new model

### controller
- Create a controller/handler file
- If `--crud` is specified, include all CRUD operations
- Generate route registrations

### service
- Create a service class with dependency injection
- If `--with-tests` is specified, also generate test file
- If `--with-docs` is specified, add JSDoc/docstring comments

### middleware
- Create a middleware function
- Include next() call and error handling

## Constraints
- Match existing code style exactly
- Use the project's established patterns for each type

Multi-Step Workflows with Checkpoints

For complex workflows in which Claude should pause for confirmation at critical points, checkpoint patterns can be built into commands:

# File: .claude/commands/major-refactor.md

Perform a major refactoring: $ARGUMENTS

## CHECKPOINT 1: Analysis
- Analyze the current state of $ARGUMENTS
- Present findings: what needs to change and why
- List every file that will be affected
- Estimate the scope: Small (1-3 files) / Medium (4-10) / Large (11+)
**STOP and wait for user approval before proceeding.**

## CHECKPOINT 2: Plan
- Present a detailed, step-by-step refactoring plan
- Include rollback strategy for each step
- Highlight any risky operations
**STOP and wait for user approval before proceeding.**

## CHECKPOINT 3: Execute
- Execute the plan one step at a time
- Run tests after each step
- If tests fail, roll back the last step and report
- After all steps complete, present the final summary
**STOP and wait for user approval to finalize.**

## If the user says "abort" at any checkpoint:
- Roll back all changes made so far
- Report what was reverted

Commands That Read CLAUDE.md

Among the most useful advanced patterns is the writing of commands that explicitly reference a project’s CLAUDE.md file. Because CLAUDE.md is automatically loaded by Claude Code as project context, commands can rely on the conventions defined there without repeating them:

# File: .claude/commands/new-feature.md

Implement a new feature following all project conventions
defined in CLAUDE.md: $ARGUMENTS

## Instructions
- Read CLAUDE.md to understand the project's coding standards,
  directory structure, and conventions
- Follow every guideline specified there — CLAUDE.md is the
  source of truth for how code should be written in this project
- If CLAUDE.md specifies a testing approach, follow it exactly
- If CLAUDE.md specifies commit message formats, use them
- If any instruction here conflicts with CLAUDE.md, CLAUDE.md wins

## Implementation
1. Plan the feature based on $ARGUMENTS
2. Implement following CLAUDE.md conventions
3. Write tests following CLAUDE.md testing guidelines
4. Format code according to CLAUDE.md style rules
5. Summarize what was done
Key Takeaway: Advanced commands combine multiple techniques: argument parsing, environment detection, checkpoints for human approval, and integration with CLAUDE.md. The objective is to design workflows that are capable while retaining human control at critical decision points.

Project Commands and User Commands

The choice between project and user commands is a design decision that affects team workflow. The following detailed comparison clarifies where each type of command should reside.

Aspect Project Commands User Commands
Location .claude/commands/ ~/.claude/commands/
Version controlled Yes—committed to git No—local to your machine
Shared with team Automatically via git Never (unless manually shared)
Available across projects Only in that project In ALL projects
Best for Team workflows, project-specific tasks Personal productivity, cross-project utilities
Examples /deploy, /create-component, /write-post /explain, /summarize, /standup-notes

 

When to Use Project Commands

Project commands are appropriate when the command is specific to the project and useful to every team member. Deployment workflows, code scaffolding that follows project conventions, and review checklists that enforce team standards all belong as project commands. The principal advantage is consistency: a new developer joining the team obtains the same set of automated workflows as everyone else, configured for the specific project.

When to Use User Commands

User commands are appropriate for personal productivity and cross-project utilities. Examples include /explain (explain any code in detail), /summarize (summarize the day’s work), or /standup-notes (generate stand-up notes from recent git history). These commands are useful in every project but reflect personal workflow rather than a team standard.

A useful heuristic: if the command references specific files, directories, or tools within the project, it is a project command. If it operates generically with any codebase, it is a user command.

Integration with CLAUDE.md

The relationship between CLAUDE.md and custom commands is one of the most important architectural decisions in a Claude Code project. CLAUDE.md functions as a constitution and custom commands as laws: commands should implement and extend the principles defined in CLAUDE.md and never contradict them.

CLAUDE.md as the Source of Truth

CLAUDE.md is loaded automatically by Claude Code at the start of every session. It defines project-wide conventions: coding style, directory structure, testing approach, deployment targets, and constraints. Custom commands inherit this context automatically; when a command directs Claude to “follow the project’s conventions,” Claude has already obtained those conventions from CLAUDE.md.

The result is that commands can be shorter and more focused. Rather than repeating the coding-style guide in every command, the guide is defined once in CLAUDE.md and referenced from commands:

# In CLAUDE.md:
## Coding Standards
- Use TypeScript strict mode
- All functions must have return types
- Use Prettier with the project's .prettierrc
- Tests use Vitest with describe/it blocks
- Components use the Composition API (no Options API)

# Then in .claude/commands/create-feature.md:
Create a new feature: $ARGUMENTS

Follow all coding standards from CLAUDE.md exactly.
...

Example: CLAUDE.md and a Command Working Together

A concrete example illustrates how the two components complement one another. Suppose CLAUDE.md contains the following:

# CLAUDE.md
## Project Structure
- API routes go in `src/routes/`
- Business logic goes in `src/services/`
- Database queries go in `src/repositories/`
- Tests mirror the source structure in `tests/`

## API Conventions
- All endpoints return JSON with `{ data, error, meta }` structure
- Use Zod for request validation
- Authentication via Bearer token in Authorization header
- Rate limiting on all public endpoints

The corresponding /api-endpoint command can then be considerably simpler because it relies on these conventions:

# .claude/commands/api-endpoint.md

Create a new API endpoint: $ARGUMENTS

Follow the project structure and API conventions defined in CLAUDE.md.

1. Create the route handler in the appropriate file under src/routes/
2. Create or update the service in src/services/
3. Create or update the repository in src/repositories/ if DB access
   is needed
4. Add Zod validation schemas for request/response
5. Create tests mirroring the source structure in tests/
6. Ensure the endpoint returns the standard { data, error, meta }
   response format

All conventions from CLAUDE.md apply — do not deviate.

The command is concise because CLAUDE.md provides the detailed context. This is a powerful pattern: conventions are defined once and referenced throughout.

Organizing Commands for Large Projects

As a command library grows, organization becomes important. A project containing twenty commands in a flat directory becomes difficult to navigate. The following strategies have proven effective in keeping the structure manageable.

Naming Conventions

A consistent naming-prefix system groups related commands:

.claude/commands/
├── deploy.md               # /deploy
├── deploy-staging.md       # /deploy-staging
├── deploy-production.md    # /deploy-production
├── create-component.md     # /create-component
├── create-service.md       # /create-service
├── create-migration.md     # /create-migration
├── review-code.md          # /review-code
├── review-security.md      # /review-security
├── test-unit.md            # /test-unit
├── test-integration.md     # /test-integration
├── test-e2e.md             # /test-e2e
└── fix-bug.md              # /fix-bug

Prefix-based naming (deploy-*, create-*, review-*, test-*) causes related commands to sort together alphabetically, simplifying discovery in the / menu.

Command Discovery

Claude Code provides a built-in discovery mechanism: typing / displays all available commands. Every command created is therefore instantly discoverable by the developer and the team. For larger command libraries, a /help command that lists all available commands with brief descriptions can be useful:

# File: .claude/commands/help.md

List all available custom commands in this project.

Read all .md files in .claude/commands/ and for each one:
1. Show the command name (filename without .md)
2. Read the first line or paragraph to get a brief description
3. Note if it accepts $ARGUMENTS

Format as a clean table:
| Command | Description | Arguments |
|---------|-------------|-----------|

Sort alphabetically by command name.

Documentation Within Commands

Every command file should begin with a clear, one-line description of its purpose. This serves two functions: it informs Claude what the command is for, and it renders the command self-documenting for team members who read the file:

# File: .claude/commands/deploy.md

Deploy the application to staging or production environments.
Usage: /deploy [staging|production]

## Steps:
...
Caution: Deeply nested subdirectory structures within .claude/commands/ should be avoided. Although organizing commands into deploy/, create/, and test/ subdirectories may appear logical, the current behaviour of Claude Code with subdirectories should be verified before adopting that structure. Flat directories with prefix-based naming represent the most reliable approach.

Common Mistakes and How to Avoid Them

Examination of numerous custom commands across teams and projects reveals certain mistakes that occur repeatedly. The following sections describe the most common pitfalls and their remedies.

Overly Vague Instructions

This is the most common mistake. The instruction “clean up the code” may mean anything from renaming variables to rewriting an entire module. Claude will make reasonable choices, but they may not be the choices the developer intends. Specify exactly what “clean up” means in the relevant context: remove unused imports, add type annotations, extract long functions, fix linter warnings, or whatever is intended.

Failure to Specify File Paths

Commands that direct Claude to “update the configuration” force the tool to guess which configuration file is meant. In a typical project, files such as config.json, .env, tsconfig.json, package.json, .eslintrc, and a dozen others may be present. Explicit instructions are preferable: “update the database configuration in config/database.yml.”

Missing Error Handling

Commands without error-handling instructions produce unpredictable results when failures occur. What should Claude do if the build fails, a file does not exist, or a test times out? Explicit error handling should be added for every step that could fail: “If the build fails, read the error output, fix the issue, and retry. If it fails a second time, stop and report the errors.”

Overly Complex Single Commands

A 200-line command file that handles deployment, testing, monitoring, rollback, notification, and documentation is fragile and difficult to maintain. If one component fails, the entire command becomes unreliable. Such files should be decomposed into focused commands: /deploy, /test, /monitor, /rollback. Each is easier to write, test, debug, and maintain.

Insufficient Testing Before Sharing

Before committing a project command for team-wide use, it should be tested thoroughly. The command should be exercised with different arguments, including edge cases such as empty arguments, incorrect file paths, and unexpected input. A command that fails on first use erodes team confidence in the entire system. Testing with --dry-run flags where possible and verifying that the output matches expectations before sharing is advisable.

Omission of Constraints

Without explicit constraints, Claude may modify files that were not intended to be changed, install unwanted packages, or push to unintended branches. Every command should include a constraints section that defines the boundaries: which files are off-limits, what operations are forbidden, and what requires explicit user confirmation.

Mistake Symptom Fix
Vague instructions Inconsistent results across runs List specific actions and expectations
No file paths Claude edits the wrong file Reference every file by its exact path
No error handling Command hangs or produces garbage on failure Add “if X fails, then do Y” for each step
Monolithic commands Hard to debug, one failure breaks everything Split into focused single-purpose commands
No testing Team loses confidence in commands Test with edge cases before committing
Missing constraints Unintended file modifications or operations Add explicit “do NOT” rules for every command

 

Real-World Command Libraries by Technology Stack

The following curated command sets for popular technology stacks provide a starting point. Each set represents the kind of command library that a mature team would maintain.

Python Stack (FastAPI / Django / Flask)

.claude/commands/
├── create-endpoint.md      # Scaffold a new API endpoint
├── create-model.md         # Create a new SQLAlchemy/Django model
├── create-migration.md     # Generate an Alembic/Django migration
├── write-tests.md          # Generate pytest tests for a module
├── review-code.md          # Code review with Python-specific checks
├── lint-fix.md             # Run ruff/flake8 and auto-fix issues
├── type-check.md           # Run mypy and fix type errors
├── deploy.md               # Deploy via Docker/Kubernetes/Lightsail
├── create-service.md       # Scaffold a new service layer class
└── create-cli.md           # Scaffold a new Click/Typer CLI command

A Python-specific /create-endpoint command would include patterns for Pydantic request/response models, dependency injection, and async handlers—conventions that differ substantially from those of JavaScript frameworks.

Node.js Stack (Express / Next.js / NestJS)

.claude/commands/
├── create-component.md     # React/Vue component with tests
├── create-page.md          # Next.js page with SSR/SSG
├── create-api-route.md     # API route handler
├── create-hook.md          # Custom React hook with tests
├── write-tests.md          # Jest/Vitest test generation
├── review-code.md          # Code review with TS/JS checks
├── lint-fix.md             # Run ESLint and Prettier fixes
├── deploy.md               # Deploy to Vercel/AWS/Netlify
├── create-middleware.md    # Express/NestJS middleware
└── storybook.md            # Generate Storybook stories

Go Stack

.claude/commands/
├── create-handler.md       # HTTP handler with middleware
├── create-service.md       # Service with interface and impl
├── create-repository.md    # Database repository pattern
├── create-migration.md     # SQL migration files
├── write-tests.md          # Table-driven test generation
├── review-code.md          # Code review with Go idiom checks
├── lint-fix.md             # Run golangci-lint and fix issues
├── create-proto.md         # Protobuf definition + generated code
├── benchmark.md            # Write and run benchmarks
└── deploy.md               # Build and deploy Go binary

DevOps Commands (Cross-Stack)

.claude/commands/
├── docker-build.md         # Build and tag Docker images
├── docker-compose-up.md    # Start all services with health checks
├── k8s-deploy.md           # Kubernetes deployment workflow
├── create-pipeline.md      # Scaffold CI/CD pipeline config
├── create-dockerfile.md    # Generate optimized Dockerfile
├── ssl-check.md            # Check SSL certificate expiry
├── log-analyze.md          # Analyze recent error logs
├── scale.md                # Scale services up or down
├── rollback.md             # Rollback to previous deployment
└── infra-audit.md          # Audit infrastructure configuration

Documentation Commands

.claude/commands/
├── document-api.md         # Generate API documentation
├── document-function.md    # Add JSDoc/docstrings to functions
├── update-readme.md        # Update README based on current state
├── changelog.md            # Generate changelog from git history
├── adr.md                  # Create Architecture Decision Record
├── runbook.md              # Generate operations runbook
└── diagram.md              # Generate Mermaid architecture diagrams

Documentation commands are particularly valuable because documentation is the task most developers avoid. Automating it with a slash command removes the friction entirely. A simple /document-api can analyse route handlers and generate comprehensive API documentation within seconds.

Tip: Begin with three to five commands that address the most frequent tasks. Additional commands can be added as repetitive workflows are identified. A well-curated library of ten to fifteen commands covers most development needs without becoming unwieldy.

Conclusion

Custom commands in Claude Code are not merely a convenience; they constitute a fundamentally different mode of working with AI in a development workflow. Rather than typing the same detailed instructions whenever a deploy, scaffold, review, or test is needed, the developer encodes that knowledge once in a Markdown file and invokes it with a single slash command for the remainder of the project’s lifetime.

The effect is immediate and measurable. Teams that adopt custom commands report substantially reduced time on repetitive workflows. The deeper benefit, however, is consistency. When every team member uses the same /deploy command, deployments follow the same process each time. When everyone uses the same /review-code command, code reviews examine the same items. Tribal knowledge that previously resided in one senior developer’s mind becomes encoded in files that the entire team can use, improve, and version-control.

A practical path forward is the following. Begin with three commands: one for the most frequent task (typically code scaffolding or deployment), one for the most disliked task (typically writing tests or documentation), and one for the team’s most significant pain point (typically code review or environment setup). These should be written following the patterns described in this guide: specific instructions, clear steps, explicit constraints, and error handling. They should be tested, refined, and committed to the repository.

Iteration follows. Whenever the developer notices that the same detailed instructions have been provided to Claude Code for a third time, those instructions should be converted into a command. When a colleague asks how to deploy or what the testing convention is, the relevant command can serve as the reference. Over time, the .claude/commands/ directory becomes a living, executable operations manual for the project, one that does not merely describe workflows but runs them.

The developers who derive the greatest benefit from AI coding tools are not those who type the fastest prompts. They are those who build systems that make every subsequent interaction faster, more consistent, and more reliable. Custom commands are the mechanism by which such a system is constructed in Claude Code. The ten commands in this guide provide a starting point; adapting them to a particular project and building from there yields substantial returns over time.

References

You Might Also Like

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *