Consistency
Same pattern every execution - no variation in quality or structure
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*Automated Approach:
You: /new-component UserProfileClaude: *Follows exact project patterns* *No clarification needed* *Consistent results every time*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 listallowed-tools: - Write - Read - Edit - AskUserQuestionargument-hint: <arg1> [optional-arg]---Key Fields:
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 stepsTemplates, 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
## ExamplesBasic: /command ExampleAdvanced: /command path/ExampleLet’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 filesallowed-tools: - Write - Read - Edit - AskUserQuestion - Globargument-hint: <ComponentName> or <path/ComponentName>---Why These Choices?
Description
Clearly states what gets generated (not just “creates component”)
Tools
Argument Hint
Shows both basic and nested usage patterns
The command follows a numbered workflow:
Parse component name from arguments
Validate component name
/^[A-Z][a-zA-Z0-9_]*$/Determine paths
Check for collisions
Generate files
ComponentName placeholders with actual component nameUpdate barrel export
Report success
Why This Works:
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## 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
1. **Generate component file**: - Use Write tool - Location: `src/components/react/ComponentName.tsx` - Use Component Template belowExplicit tool, location, and template reference (ComponentName is a placeholder)
Parse the arguments, validate the name, create files, and report success.Run-on sentence - hard to follow
1. **Parse arguments** - Extract component name - Extract optional path
2. **Validate name** - Check PascalCase - Show error if invalid
3. **Create files** - Component - Test - Story
4. **Report success** - List files - Show next stepsClear hierarchy and sequence
Component name must be PascalCase.No examples of what’s valid
Component name must be PascalCase.
**Valid**: `UserProfile`, `LoginForm`, `EventCard`**Invalid**: `userProfile`, `user-profile`, `User Profile`Clear examples of both valid and invalid
Create a TypeScript component with props.Description only - no concrete example
### Component Template
```typescriptexport type ComponentNameProps = { children?: React.ReactNode}
export const ComponentName: React.FC<ComponentNameProps> = ({ children}) => { return <div>{children}</div>}```Exact code template with placeholders for ComponentName
Create 4 files.No collision handling
5. **Check for collisions**: - Use Read tool to check if component exists - If exists, ask user to confirm overwrite - If user cancels, stop executionGraceful handling of existing files
Use path aliases.No explanation why
## Important Notes
- **ALWAYS use path aliases** with `#` prefix - Example: `import X from '#components/react/X'`- **NEVER use relative imports** - Example: `import X from '../../components/X'`- This ensures consistency with project standardsContext and rationale included
Report that files were created.No format specified
## Success Message Format
\`\`\`✅ Component scaffold created successfully!
Files generated: 📄 src/components/react/ComponentName.tsx 🧪 tests/components/ComponentName.react.test.tsx 📖 src/components/react/ComponentName.stories.tsx 📦 src/components/react/index.ts (updated)
Next steps: 1. Implement component logic 2. Write comprehensive tests 3. Run: npm run storybook\`\`\`Formatted template with emojis and next steps (ComponentName is a placeholder)
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 changesInput 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]Create test file
cat > .claude/commands/test-command.md << 'EOF'---description: Test commandallowed-tools: - Write---
# Test Command
1. Write a file to `/tmp/test.txt`2. Report success
## Template
Hello from test command!EOFInvoke command
/test-commandVerify behavior
Test edge cases
# Missing arguments/test-command
# Invalid arguments/test-command invalid@name
# Existing files/test-command ExistingComponentRefine instructions
Based on results, update:
Solutions:
.claude/commands/my-command.md (matches command name)Solutions:
Solutions:
Solutions:
allowed-tools in frontmatterSolutions:
ComponentName, filename)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
Claude Code Documentation
Official Claude Code documentation