Level 3: Builder — Automate Repetition with Custom Skills
Typing the same instructions every time is inefficient. Having to type “Please review this code. Consider bugs, performance, and type definitions…” every time you want a code review is the Level 2 way of working. With custom slash commands, a single /review executes those instructions.
Target audience: Anyone who has MCP integration set up and wants to turn repetitive tasks into commands to share with their team.
Estimated learning time: Read 20min + Practice 30min
How Custom Slash Commands Work
Section titled “How Custom Slash Commands Work”In Claude Code, you can create your own slash commands by placing Markdown files in the .claude/commands/ folder.
your-project/
├── .claude/
│ ├── settings.json
│ └── commands/
│ ├── review.md → callable with /review
│ └── changelog.md → callable with /changelog
└── CLAUDE.mdThe contents of the Markdown file become the command’s instructions.
The filename becomes the command name (review.md → /review).
Command Example 1: /review (Code Review)
Section titled “Command Example 1: /review (Code Review)”.claude/commands/review.md:
# Code Review
Check the current diff (git diff) and review from the following perspectives:
1. **Potential bugs** — null references, boundary errors, missing exception handling
2. **Performance** — N+1 queries, unnecessary loops, memory leaks
3. **Type consistency** — missing type definitions, implicit type conversions
4. **Security** — SQL injection, authentication, input validation
## Output Format
List issues in the format "Severity (High/Medium/Low): filename — description."
If there are no issues, respond with "Review complete: no issues."How to invoke:
/reviewCommand Example 2: /changelog (Release Note Generation)
Section titled “Command Example 2: /changelog (Release Note Generation)”.claude/commands/changelog.md:
# Release Note Generation
Check the recent commit history with `git log --oneline` and generate release notes in the following format.
## Output Format
```markdown
## [Version] - YYYY-MM-DD
### New Features
- [Summarize feat commits]
### Bug Fixes
- [Summarize fix commits]
### Other
- [Summarize chore/refactor/docs commits]Constraints
Section titled “Constraints”- Rephrase commit messages in terms that non-engineers can also understand
- Group internal refactoring and CI changes under “Other”
How to invoke:
/changelog
## Receiving Arguments with $ARGUMENTS
When you want to pass arguments to a command, use `$ARGUMENTS` inside the Markdown file.
`.claude/commands/fix.md`:
```markdown
# Bug Fix
Please fix the following bug:
$ARGUMENTS
## Steps
1. First write a test case that reproduces the bug
2. Confirm the test fails
3. Fix the bug
4. Confirm the test passes
5. Update related documentation and commentsHow to invoke:
/fix GET /users/{id} returns 500 when user does not exist“GET /users/{id} returns 500 when user does not exist” is passed into the $ARGUMENTS placeholder.
Regular Instructions vs. Custom Skills
Section titled “Regular Instructions vs. Custom Skills”| Item | Regular instructions | Custom skills |
|---|---|---|
| How to invoke | Type out text every time | A single /command-name |
| Consistency | Tends to vary between sessions | Same instructions executed every time |
| Team sharing | Difficult | Git-manage .claude/commands/ and everyone can use them |
| Passing arguments | Write an explanation every time | Just append after $ARGUMENTS |
By managing the .claude/commands/ folder with git, the whole team can use the same commands.
Hands-On Tutorial
Section titled “Hands-On Tutorial”If you want to learn by doing, check out the tutorial.
Hands-on tutorial for this level →