Skip to content

Creating Slash Commands

Learn how to create custom slash commands for Claude Code, using the retired /new-component command as a worked example. Master prompt engineering techniques for building intelligent development automation tools.

Slash commands are markdown files in .claude/commands/ that give Claude specific instructions for performing tasks. They’re essentially specialized prompts that execute when invoked with /command-name.

Manual Approach:

You: "Create a React component called UserProfile with tests and stories"
Claude: *May or may not follow project patterns*
*Needs clarification questions*
*Results vary based on interpretation*
  • Inconsistent results
  • Requires explaining conventions
  • Easy to forget steps

Consistency

Same pattern every execution - no variation in quality or structure

Speed

No explaining project conventions - instant results

Completeness

Never forget a step - all requirements captured

Intelligence

Claude adapts to edge cases and validates input

Documentation

Command file documents the process for the team

Reusability

Any team member can use it - knowledge sharing

Every slash command file has three essential parts:

---
description: Brief description shown in command list
allowed-tools:
- Write
- Read
- Edit
- AskUserQuestion
argument-hint: <arg1> [optional-arg]
---

Key Fields:

  • description: One-line summary (shown when listing commands)
  • allowed-tools: Which Claude tools the command can use
  • argument-hint: Shows users expected argument format

Clear, imperative instructions telling Claude exactly what to do:

## Instructions
1. **Parse arguments**
- Extract component name
- Validate format
2. **Generate files**
- Use Write tool for each file
- Follow templates below
3. **Report success**
- List generated files
- Provide next steps

Templates, examples, validation rules that Claude uses:

## Templates
### Component Template
\`\`\`typescript
// Template content with placeholders for component name
\`\`\`
## Validation Rules
- Must be PascalCase
- No special characters
## Examples
Basic: /command Example
Advanced: /command path/Example

Let’s analyze the /new-component command to understand effective prompt engineering. The command itself was retired from .claude/commands/ in September 2026 after a usage audit found no invocations; its prompt is reproduced here because it remains a good example of the structure.

---
description: Generate React component scaffold with test, story, and barrel export files
allowed-tools:
- Write
- Read
- Edit
- AskUserQuestion
- Glob
argument-hint: <ComponentName> or <path/ComponentName>
---

Why These Choices?

Description

Clearly states what gets generated (not just “creates component”)

Tools

  • Write: Create new files
  • Read: Check for existing files
  • Edit: Update barrel exports
  • AskUserQuestion: Interactive mode
  • Glob: Find existing components

Argument Hint

Shows both basic and nested usage patterns

The command follows a numbered workflow:

  1. Parse component name from arguments

    • If provided: Extract name and path
    • If not provided: Use AskUserQuestion
  2. Validate component name

    • Must be PascalCase
    • Regex: /^[A-Z][a-zA-Z0-9_]*$/
    • Show helpful error if invalid
  3. Determine paths

    • Calculate all 4 file paths
    • Component, test, story, barrel export
  4. Check for collisions

    • Use Read tool to check if exists
    • Warn user if overwriting
  5. Generate files

    • Use Write tool with templates
    • Replace ComponentName placeholders with actual component name
  6. Update barrel export

    • Read existing index.ts
    • Add new export
    • Sort alphabetically
  7. Report success

    • Show checkmarks
    • List files
    • Provide next steps

Why This Works:

  • ✅ Sequential: Clear order of operations
  • ✅ Conditional: Handles missing arguments
  • ✅ Defensive: Checks for collisions
  • ✅ Complete: Doesn’t skip steps
  • ✅ Helpful: Provides guidance at the end

Templates use placeholder syntax for variable replacement:

export type ComponentNameProps = {
children?: React.ReactNode
className?: string
}
export const ComponentName: React.FC<ComponentNameProps> = ({
children,
className
}) => {
return <div className={className}>{children}</div>
}

Key Techniques:

  • ComponentName placeholders replaced with actual component name
  • Multiple placeholders in same template
  • Includes project patterns (ComponentNameProps, displayName)
## Validation Rules
**Component Name**:
- Must be PascalCase (e.g., `UserProfile`, `LoginForm`)
- No special characters except underscore
- Cannot start with number
- Regex: `/^[A-Z][a-zA-Z0-9_]*$/`
**Valid names**:
- `UserProfile` ✅
- `LoginForm` ✅
- `EventCard` ✅
**Invalid names**:
- `userProfile` ❌ (camelCase)
- `user-profile` ❌ (kebab-case)
- `User Profile` ❌ (contains space)

Provide error message templates for consistency:

If component name is invalid:
\`\`\`
❌ Invalid component name: "user-profile"
Component names must be PascalCase.
Valid examples:
- UserProfile
- LoginForm
- EventCard
Please try again.
\`\`\`

This ensures Claude gives consistent, helpful errors with example input.

You should create a component file.

Too vague - no details on how or where

Parse the arguments, validate the name, create files, and report success.

Run-on sentence - hard to follow

Component name must be PascalCase.

No examples of what’s valid

Create a TypeScript component with props.

Description only - no concrete example

Create 4 files.

No collision handling

Use path aliases.

No explanation why

Report that files were created.

No format specified

Simple file creation with validation:

## Instructions
1. **Parse arguments**
- Extract filename from `$ARGUMENTS`
- Validate format
2. **Generate file**
- Use Write tool
- Location: `src/filename.tsx` (filename is a placeholder)
- Use template below
3. **Report success**
## Template
\`\`\`typescript
// Generated file content
\`\`\`

Creating multiple related files:

## Instructions
1. **Determine file paths**
- Component: `src/components/Name.tsx`
- Test: `tests/Name.test.tsx`
- Story: `src/components/Name.stories.tsx`
2. **Generate all files**
- Use Write tool for each
- Replace Name placeholders in templates
## Templates
### Component Template
\`\`\`typescript
...
\`\`\`
### Test Template
\`\`\`typescript
...
\`\`\`

Prompting users when arguments missing:

## Instructions
1. **Check for arguments**
- If provided, use directly
- If missing, use AskUserQuestion
2. **Use AskUserQuestion**
- Question: "What is the component name?"
- Validate response
- Re-prompt if invalid (max 3 times)

Modifying existing files safely:

## Instructions
1. **Read existing file**
- Use Read tool
- Parse current content
2. **Make updates**
- Add new entry
- Sort alphabetically
- Preserve formatting
3. **Write updated file**
- Use Edit or Write tool
- Verify changes

Input validation with helpful errors:

## Instructions
1. **Validate input**
- Check against rules
- If invalid, show error message
- Provide examples of valid input
- Allow retry
## Validation Rules
[Specific rules with regex]
## Error Messages
[Helpful error templates]
  1. Create test file

    Terminal window
    cat > .claude/commands/test-command.md << 'EOF'
    ---
    description: Test command
    allowed-tools:
    - Write
    ---
    # Test Command
    1. Write a file to `/tmp/test.txt`
    2. Report success
    ## Template
    Hello from test command!
    EOF
  2. Invoke command

    Terminal window
    /test-command
  3. Verify behavior

    • Did it execute correctly?
    • Did it follow instructions?
    • Were errors handled gracefully?
    • Is output helpful?
  4. Test edge cases

    Terminal window
    # Missing arguments
    /test-command
    # Invalid arguments
    /test-command invalid@name
    # Existing files
    /test-command ExistingComponent
  5. Refine instructions

    Based on results, update:

    • Clearer wording
    • Better examples
    • More validation
    • Improved error messages

Solutions:

  1. Check file is in .claude/commands/
  2. Verify filename is my-command.md (matches command name)
  3. Ensure YAML frontmatter is present
  4. Restart Claude Code or reload window

Solutions:

  1. Make instructions more explicit and imperative
  2. Break complex steps into smaller sub-steps
  3. Use numbered lists for sequential operations
  4. Add examples showing expected behavior
  5. Include validation checkpoints

Solutions:

  1. Reduce ambiguity in instructions
  2. Provide explicit templates (not descriptions)
  3. Include validation rules with regex
  4. Add error handling for edge cases
  5. Test with various inputs

Solutions:

  1. Add tool to allowed-tools in frontmatter
  2. Check tool name matches exactly (case-sensitive)
  3. Verify tool is available in Claude Code

Solutions:

  1. Ensure instructions explicitly say “Replace placeholders with actual values”
  2. Use consistent placeholder syntax (e.g., ComponentName, filename)
  3. Show examples of replacement in instructions
  4. Test placeholder names (avoid conflicts)

Be Explicit

Don’t assume Claude knows project conventions

Provide Examples

Show don’t just tell

Include Templates

Exact code is better than descriptions

Validate Input

Check before generating

Handle Errors

Graceful failure with helpful messages

Report Progress

Show what was done

Provide Next Steps

Guide user after completion

Test Thoroughly

Try edge cases and invalid inputs

Document Well

Explain why, not just what

Iterate

Refine based on real usage

CLAUDE.md

Project patterns and conventions reference

View Patterns

Claude Code Documentation

Official Claude Code documentation

View Docs