10 Must-Use Custom Slash Commands in Claude Code: Eliminate Prompt Drift Forever
Every time you type the same prompt in Claude Code, you get slightly different results. Different formatting. Different depth. Different assumptions. This is prompt drift — and it is silently degrading your development workflow.
Custom slash commands solve this completely. You write the prompt once as a markdown file, and every invocation produces consistent, repeatable results. Here are 10 commands that every SDET and developer should set up today.
Contents
How Custom Commands Work
Create a .claude/commands/ directory in your project. Each .md file becomes a slash command:
env-check.mdbecomes/project:env-checkpreflight.mdbecomes/project:preflight- Personal commands go in
~/.claude/commands/and show as/user:command-name
Commands support two powerful features:
$ARGUMENTS— captures text after the command name (e.g.,/project:explain-func calculateTotalpasses “calculateTotal” into the prompt)!`shell command`— injects shell output directly into the prompt (e.g.,!`git diff --cached`passes your staged changes)
Command 1: /env-check — Validate Your Dev Environment
When to use: After cloning a repo, switching branches, or returning to a project after time away.
# .claude/commands/env-check.md
Check my local development environment for this project.
Verify:
1. All required tools are installed (node, npm, python, docker, etc.)
2. Correct versions match what's in package.json / .tool-versions
3. Required environment variables exist in .env (compare to .env.example)
4. Dependencies are installed and up to date (npm ci / pip install)
5. Database/services are running (Docker containers, local servers)
6. Build compiles without errors
For each check:
- PASS: Show green checkmark and version
- FAIL: Show what's wrong and the exact command to fix it
End with a summary: "Ready to develop" or "N issues need fixing"
Why it matters: Instead of discovering a missing env variable 20 minutes into debugging, catch everything upfront in 30 seconds.
Command 2: /orient — Rebuild Context After /clear
When to use: After running /clear to reset your conversation, or starting a new session on an existing project.
# .claude/commands/orient.md
Rebuild my working context for this project.
Read and summarize:
1. CLAUDE.md — project conventions and key commands
2. package.json / pyproject.toml — dependencies and scripts
3. Recent git log (last 10 commits) — what's been happening
4. Current git status — any uncommitted work
5. Open TODOs in the codebase (grep for TODO, FIXME, HACK)
Then tell me:
- What this project does (one sentence)
- The tech stack
- What was last worked on
- Any pending work or issues
- Suggested next actions
Why it matters: Context recovery after /clear usually takes 5-10 minutes of re-explaining your project. This command does it in seconds.
Command 3: /preflight — Pre-Commit Quality Scan
When to use: Before every git commit. This is your personal code reviewer.
# .claude/commands/preflight.md
Scan all staged changes for issues before I commit.
Review these staged changes:
!`git diff --cached`
Check for:
1. console.log / print / debugger statements left in
2. Hardcoded secrets, API keys, or passwords
3. TODO/FIXME comments that should be resolved before commit
4. Commented-out code blocks (dead code)
5. Missing error handling (try/catch, null checks)
6. Typos in user-facing strings
7. Import statements for unused modules
IMPORTANT: Report issues only. Do NOT fix anything.
Format: file:line — issue description — severity (critical/warning/info)
Design principle: This command deliberately reports without fixing. You decide what to address. It is a scanner, not an auto-fixer.
Command 4: /dissect — Deep File Review
When to use: Before deploying production-critical modules, or when reviewing unfamiliar code.
# .claude/commands/dissect.md
Perform a deep structural review of: $ARGUMENTS
For each file specified, analyze:
## Structure
- Function/method count and complexity
- Dependency chain (what it imports, what imports it)
- Lines of code vs. lines of logic (signal-to-noise ratio)
## Quality
- Functions longer than 30 lines (candidates for extraction)
- Nested conditionals deeper than 3 levels
- Magic numbers or hardcoded values
- Missing TypeScript types or any usage
## Risk
- Error handling coverage (which functions lack try/catch)
- Race condition potential (shared state, async without guards)
- Security surface (user input handling, SQL construction)
## Recommendations
- Top 3 refactoring priorities with estimated effort
Usage: /project:dissect src/services/PaymentService.ts src/utils/auth.ts
Command 5: /testmatch — Generate Tests That Match Your Style
When to use: When adding test coverage to new or existing code.
# .claude/commands/testmatch.md
Generate tests for: $ARGUMENTS
BEFORE writing any tests:
1. Read 3 existing test files in the same directory
2. Identify the patterns: naming convention, assertion style,
fixture usage, describe/it structure, data setup approach
3. Note the testing library and custom helpers used
THEN generate tests that:
- Follow the EXACT same patterns (naming, structure, helpers)
- Cover: happy path, error cases, edge cases, boundary values
- Use existing test utilities and fixtures (don't create new ones)
- Include both positive and negative assertions
The generated tests should look like a teammate wrote them,
not like AI generated them.
Why this is different: Most AI-generated tests look generic. This command forces Claude to learn your team’s testing patterns first, then generate code that matches.
Command 6: /explain-func — Why-Focused Documentation
When to use: Documenting complex logic that future developers need to understand.
# .claude/commands/explain-func.md
Document the function/method: $ARGUMENTS
Write documentation that answers WHY, not just WHAT.
Include:
1. **Purpose**: Why does this function exist? What problem does it solve?
2. **Context**: What calls this? What business rule does it implement?
3. **Algorithm**: Step-by-step explanation of the logic (not line-by-line)
4. **Edge cases**: What inputs cause special behavior? Why?
5. **Side effects**: Does it modify state, call APIs, write to DB?
6. **Historical context**: Any non-obvious decisions (check git blame)
Format as a JSDoc/docstring comment ready to paste above the function.
Avoid restating what the code literally does — explain the reasoning.
Command 7: /refactor-safe — Refactor Without Breaking APIs
When to use: Improving internal code quality without changing any public interfaces.
# .claude/commands/refactor-safe.md
Refactor the internals of: $ARGUMENTS
CONSTRAINTS (non-negotiable):
- Do NOT change any public function signatures
- Do NOT change any exported types/interfaces
- Do NOT change any API response formats
- Do NOT rename any public methods or properties
- All existing tests must still pass without modification
ALLOWED improvements:
- Extract private helper functions from long methods
- Simplify nested conditionals (guard clauses, early returns)
- Replace magic numbers with named constants
- Improve variable names for clarity (internal only)
- Remove dead code paths
- Add missing error handling
After refactoring, run the test suite and confirm all tests pass.
Safety principle: The constraint block ensures Claude cannot accidentally break your API consumers. Internal quality improves while external contracts stay identical.
Command 8: /ship — Validate and Generate PR Description
When to use: Before opening a pull request.
# .claude/commands/ship.md
Prepare this branch for a pull request.
Step 1 — Pre-flight validation:
- Run the test suite. If tests fail, STOP and report failures.
- Check for console.log/debugger artifacts in staged files.
- Verify no .env or secret files are staged.
Step 2 — Analyze the changes:
!`git log main..HEAD --oneline`
!`git diff main..HEAD --stat`
Step 3 — Generate PR description:
## Summary
(2-3 sentences explaining WHAT changed and WHY)
## Changes
(Bulleted list of specific changes, grouped by area)
## Testing
(What was tested, how to verify)
## Risk Assessment
(What could break, migration steps if any)
Step 4 — Size check:
If diff exceeds 500 lines, suggest how to split into smaller PRs.
Command 9: /migrate-draft — Database Migration With Rollback
When to use: Planning any database schema change.
# .claude/commands/migrate-draft.md
Draft a database migration for: $ARGUMENTS
BEFORE writing the migration:
1. Read existing migrations to understand naming convention and style
2. Check the current schema for the affected tables
3. Identify any foreign key constraints or indexes involved
Generate:
1. UP migration (the change)
2. DOWN migration (exact rollback)
3. Data migration script (if existing data needs transformation)
4. Estimated execution time for production (based on table size)
Safety checklist:
- [ ] Migration is idempotent (safe to run twice)
- [ ] Rollback restores exact previous state
- [ ] No data loss in either direction
- [ ] Backward compatible with current application code
- [ ] Index additions use CONCURRENTLY (if PostgreSQL)
Command 10: /debt-scan — Technical Debt Audit
When to use: Periodic project health checks (monthly or per-sprint).
# .claude/commands/debt-scan.md
Scan the codebase for technical debt patterns.
Check for:
1. **Dead code**: Unused exports, unreachable branches, commented blocks
2. **Duplication**: Similar logic in multiple places (DRY violations)
3. **Complexity**: Functions with cyclomatic complexity > 10
4. **Outdated deps**: packages with major version updates available
5. **Missing tests**: Public functions/endpoints with zero test coverage
6. **TODO archaeology**: TODOs older than 6 months (check git blame)
7. **Type safety**: any/unknown usage, missing return types
8. **Config drift**: Inconsistencies between environments
For each finding:
- Severity: critical / high / medium / low
- Location: file:line
- Estimated fix effort: quick (< 1hr) / medium (1-4hr) / large (1+ day)
- Suggested fix approach
End with a Debt Score: 0 (pristine) to 100 (rewrite territory)
Bonus: /changelog — Generate Release Notes
# .claude/commands/changelog.md
Generate release notes from recent commits.
Commits since last tag:
!`git log $(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~20)..HEAD --oneline`
Organize into sections:
## New Features
## Bug Fixes
## Improvements
## Breaking Changes
For each entry:
- Write from the USER's perspective, not the developer's
- "Added dark mode support" not "Implemented ThemeContext provider"
- Link to PR number if visible in commit message
If there are breaking changes, add a Migration Guide section.
Setting Up Your Commands
# Create the commands directory
mkdir -p .claude/commands
# Create your first command
cat > .claude/commands/preflight.md << 'EOF'
Scan staged changes for issues before commit.
Review: !`git diff --cached`
Check for: console.log, secrets, TODOs, dead code.
Report only. Do NOT fix.
EOF
# Use it
# In Claude Code, type: /project:preflight
Key Design Patterns
| Pattern | Commands | Why |
|---|---|---|
| Guard clauses | /preflight, /ship | Report issues without fixing — you stay in control |
| Convention matching | /testmatch, /migrate-draft | Learn existing patterns before generating new code |
| Safety constraints | /refactor-safe, /ship | Explicit boundaries prevent unintended changes |
| Shell injection | /preflight, /ship, /changelog | Real-time context from git diff, git log, etc. |
Project vs Personal Commands
| Scope | Location | Prefix | Use Case |
|---|---|---|---|
| Project | .claude/commands/ | /project: | Team conventions, project-specific workflows |
| Personal | ~/.claude/commands/ | /user: | Your coding style, preferences, across all projects |
Pro tip: Commit .claude/commands/ to your repo. Your entire team gets the same commands, the same quality checks, and zero prompt drift across every engineer.
Advanced: YAML Frontmatter for Tool Permissions
---
description: "Run pre-commit quality checks on staged files"
allowed-tools:
- Bash
- Read
- Grep
- Glob
---
Scan staged changes for issues...
Frontmatter lets you restrict which tools a command can use and add a description that helps Claude decide when to suggest the command.
FAQ
Can I use custom commands without Claude Code?
No. Custom slash commands are a Claude Code CLI feature. They require the .claude/commands/ directory structure and the Claude Code runtime to parse and execute. However, you can copy the prompt content into any LLM chat manually.
How many custom commands should I create?
Start with 3-4 that match your daily workflow (preflight, testmatch, and ship are good starting points). Add more as you notice yourself typing the same prompt repeatedly. If you have more than 15, consider organizing into subdirectories.
Do commands work with all programming languages?
Yes. Commands are language-agnostic prompts. Claude Code adapts to whatever language and framework your project uses. The same /preflight command works for a Python Flask project and a TypeScript Next.js project.
Can commands call other commands?
Not directly. But you can create a "meta" command that includes the instructions from multiple commands. For example, a /pre-release command that combines the logic of /preflight + /ship + /changelog.
What is the difference between commands and skills?
Commands require explicit invocation (/project:preflight). Skills trigger automatically when Claude detects a matching task. Use commands for workflows you consciously initiate, skills for rules that should always apply.
