Claude Code: how to use custom slash commands for your project
Claude Code ships with built-in slash commands like /compact, /clear, and /review. But the real power is in custom project commands — your own shortcuts baked into the codebase.
Here's how to build them and why they're worth setting up.
What are custom slash commands?
A custom slash command is a markdown file in .claude/commands/ that Claude reads as a reusable prompt template. When you type /project:migrate-db, Claude reads the file, substitutes any arguments, and runs the full instruction.
Think of them as shell aliases, but for AI prompts.
The file structure
your-project/
├── .claude/
│ └── commands/
│ ├── migrate-db.md
│ ├── review-pr.md
│ └── add-test.md
└── src/
Each .md file becomes /project:filename.
Example 1: database migration helper
Create .claude/commands/migrate-db.md:
Create a database migration for the following change: $ARGUMENTS
Requirements:
- Use the existing migration format in /db/migrations/
- Include both up() and down() functions
- Add a descriptive comment block at the top
- Follow naming convention: YYYYMMDD_description.js
- Check for existing columns before adding
- Output the filename you'll create before writing it
Now type:
/project:migrate-db add user_preferences column as JSONB with default {}
Claude reads the full template plus your argument, generates a migration that matches your existing patterns.
Example 2: PR review assistant
Create .claude/commands/review-pr.md:
Review the following git diff for: $ARGUMENTS
Focus on:
1. Logic errors that tests might miss
2. Security concerns (injection, auth bypass, data exposure)
3. Missing error handling
4. Performance issues (N+1 queries, missing indexes)
5. Inconsistencies with existing code style in this repo
For each issue, show the problematic line and suggest the fix.
End with a one-line summary: APPROVE / REQUEST_CHANGES + reason.
Usage:
/project:review-pr authentication refactor in auth.js
Then paste the diff or tell Claude to run git diff HEAD~1.
Example 3: test generator with your conventions
Create .claude/commands/add-test.md:
Write tests for: $ARGUMENTS
Project test conventions:
- Framework: Jest + Supertest
- Test files: same directory as source, *.test.js suffix
- Use beforeAll/afterAll for DB setup
- Mock external APIs using jest.mock()
- Test happy path, error cases, and edge cases
- No snapshot tests — write explicit assertions
Check the existing tests in this directory first and match their structure exactly.
Usage:
/project:add-test the createUser function in /src/users/service.js
The $ARGUMENTS variable
Anything you type after the command name becomes $ARGUMENTS in the template. If you type nothing, $ARGUMENTS is empty — so write your templates to handle both cases gracefully.
# With arguments
/project:add-test createUser function → $ARGUMENTS = "createUser function"
# No arguments
/project:add-test → $ARGUMENTS = ""
For commands that need explicit input, add a guard at the top of your template:
{{#unless ARGUMENTS}}Please specify what to test.{{/unless}}
Or just document it clearly so you never run it blank.
Commands that don't need arguments
Some commands are pure project shortcuts with no variable input:
Create .claude/commands/prep-deploy.md:
Prepare this project for deployment:
1. Run `npm test` and show me any failures
2. Run `npm run lint` and fix any errors automatically
3. Check for any console.log() statements in /src and remove them
4. Verify all environment variables in .env.example are documented in README
5. Run `npm run build` and confirm it succeeds
6. Show me the git diff summary of all changes made
Do these steps in order. Stop and ask if any step has unexpected failures.
Run with: /project:prep-deploy
No arguments needed — it's a complete workflow.
Sharing commands across a team
Because .claude/commands/ is a real directory in your repo, you commit it like any other file:
git add .claude/commands/
git commit -m "Add Claude Code project commands"
git push
Every team member gets the same commands. New engineers joining the project immediately have access to migrate-db, review-pr, and add-test — with your project's exact conventions baked in.
This is the hidden value: custom commands encode your team's standards into Claude's behavior. You stop explaining "we do it this way" and start typing /project:our-way.
Global commands (not project-specific)
For commands you want everywhere, put them in ~/.claude/commands/ instead:
~/.claude/
└── commands/
├── explain-error.md
├── git-commit.md
└── refactor-function.md
These show up as /user:explain-error, /user:git-commit — available in every project, not tracked in any repo.
Rate limits during long command chains
Custom commands that trigger multiple file writes or test runs can hit Claude Code's API rate limits mid-execution. The session pauses and you lose context.
One fix: set ANTHROPIC_BASE_URL to a proxy that removes the rate limit cap:
export ANTHROPIC_BASE_URL=https://simplylouie.com
SimplyLouie is a $2/month Claude API proxy — same claude-3-5-sonnet model, no per-session rate limits. Long command chains run to completion without interruption.
Quick reference
| Location | Prefix | Scope |
|---|---|---|
.claude/commands/name.md |
/project:name |
This repo only |
~/.claude/commands/name.md |
/user:name |
All projects |
| Built-in |
/compact, /clear, etc. |
Always available |
Start small
Don't build 20 commands on day one. Start with the task you do most often:
- What do you explain to Claude repeatedly?
- What multi-step workflow do you run in every session?
- What project convention does Claude keep getting wrong?
Each answer is a command worth writing. One good command that saves 5 minutes daily is worth more than a library of commands you never use.
Claude Code hitting rate limits mid-command? SimplyLouie.com — $2/month, no rate limit interruptions, same model.
Top comments (0)