Skip to content

Custom Commands for Fixed Prompts

Create slash commands that execute predefined prompts. Build /review, /refactor, /test that do exactly what you want every time.

You keep typing the same prompts. "Review this file for bugs." "Write unit tests for the function I just changed." "Refactor this to use early returns." Each time you phrase it slightly differently. Each time you get slightly different results. Annoying.

Custom commands kill this problem. Write the prompt once, save it as a file, run it with a slash command forever.

What Custom Commands Actually Are

A markdown file in a specific folder. That's it. Claude Code picks it up as a slash command. No config files, no plugin system, no registration. One markdown file, one command.

Create review.md inside .claude/commands/ in your project. Type /review in any Claude Code session. It runs whatever instructions are in that file. The filename becomes the command name.

Now, these commands have been merged into the newer skills system. A file at .claude/commands/review.md and a skill at .claude/skills/review/SKILL.md both create /review and work identically. Old commands files keep working. Skills just add optional features (supporting files, frontmatter, auto-invocation). For anything new, use skills.

Building Your First Command

Create the directory, add a markdown file:

mkdir -p .claude/skills/review

Now create .claude/skills/review/SKILL.md with your prompt:

---
name: review
description: Review code for bugs and issues
---
 
Review the current changes for:
1. Logic errors and off-by-one bugs
2. Missing error handling
3. Security issues (SQL injection, XSS, unvalidated input)
4. Performance problems (N+1 queries, unnecessary re-renders)
5. Violations of our project's coding standards in CLAUDE.md
 
Be specific. Point to exact lines. Suggest fixes, not just problems.

That's it. Type /review next session and it runs those exact instructions. Every time. No retyping, no forgetting that one security check you always mean to include but don't.

Parameterized Commands

Commands get genuinely useful once you add parameters. The $ARGUMENTS placeholder gets replaced with whatever you type after the command name.

A /fix-issue skill:

---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
 
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Understand the requirements
3. Implement the fix
4. Write tests
5. Create a commit

Type /fix-issue 123, and $ARGUMENTS becomes "123". Claude Code reads GitHub issue #123, implements the fix, writes tests, commits. One command, full workflow.

You can grab individual arguments with $ARGUMENTS[0], $ARGUMENTS[1], or shorthand $1, $2 when your command needs multiple distinct inputs.

The disable-model-invocation: true line is important. It prevents Claude Code from auto-triggering this skill during normal conversation. You absolutely want this for commands that commit code or interact with external services. Without it, Claude Code might decide on its own that it's time to deploy. Bad idea.

Practical Commands Worth Building

Three commands that pay for themselves immediately.

A /refactor command that enforces your team's style:

---
name: refactor
description: Refactor code to match project standards
---
 
Refactor $ARGUMENTS to follow our coding standards:
- Use early returns instead of nested conditionals
- Extract magic numbers into named constants
- Keep functions under 30 lines
- Use descriptive names with auxiliary verbs (isLoading, hasError)
- Remove dead code and unused imports
 
Do not change behavior. Only restructure.

A /test command that writes tests the way you actually want them:

---
name: test
description: Write tests for specified code
---
 
Write tests for $ARGUMENTS.
- Use the testing framework already in this project
- Cover happy path, edge cases, and error states
- Use descriptive test names that explain the expected behavior
- Mock external dependencies, never hit real APIs
- Aim for at least 90% branch coverage on the target code

Try it. Create the /review skill in your current project. Make a small change, type /review. Compare that to typing "review my code" freehand. The structured version catches more because it runs a specific checklist every time instead of whatever Claude Code feels like checking.

Personal vs. Project Commands

Project commands live in .claude/skills/ (or .claude/commands/) inside your repo. Committed to git, shared with the team. Everyone gets the same /review with the same standards.

Personal commands live in ~/.claude/skills/ (or ~/.claude/commands/) in your home directory. Yours across every project. Great for your preferred commit message format, your debugging workflow, how you like code explained.

When both exist with the same name, project wins. Teams can override your personal defaults when needed.

Recap

Custom command = markdown file where the filename becomes a slash command. Dead simple. Skills (.claude/skills/name/SKILL.md) are the recommended format since they support frontmatter and supporting files. Use $ARGUMENTS for flexibility, and always set disable-model-invocation: true on anything that does destructive or heavy operations. Project commands standardize your team; personal commands are your private shortcuts.

Mastering Claude Code

Lesson 44 of 70