What are Commands?
Commands are slash commands that you invoke by typing /command-name. They're markdown files stored in .claude/commands/ directories. When you type a slash command, the entire contents of the markdown file get injected into Claude's context as instructions.
Commands range from simple ("run tests and report failures") to complex (multi-phase orchestration workflows that launch parallel subagents, triage results, and verify outcomes).
You can also trigger commands conversationally — if you mention a topic that's clearly related to an existing command, Claude may suggest or invoke it. But explicit /command-name invocation is the primary pattern.
How Commands Work
- You type
/my-commandin Claude Code - Claude Code finds
commands/my-command.md - The entire markdown content gets injected into Claude's context
- Claude reads the instructions and follows them, using its tools
The key insight: commands don't run code themselves. They're instructions that Claude reads and follows. Claude's intelligence handles the coordination — deciding when to run tools, how to interpret results, and when to adapt.
What happens when you type /my-command in Claude Code?
Anatomy of a Command
---
description: Deploy the application to production
allowed-tools: Bash(npm run build:*), Bash(npx vercel:*)
---
# Deploy
1. Run `npm run build` and check for errors
2. If build succeeds, run `npx vercel --prod`
3. Display the deployment URL
4. Run a quick smoke test on the URLFields
| Field | Purpose | Example |
|---|---|---|
description | What the /slash-command does | "Deploy to Vercel" |
allowed-tools | Pre-approved tools (skip permission prompts) | Read, Bash(npm:*), Task(scout) |
The allowed-tools field is important for automation — without it, Claude hits permission prompts mid-workflow, breaking the flow.
What does the allowed-tools field in a command's frontmatter do?
Dynamic Context Injection
Commands support — shell commands whose output gets injected into the prompt before Claude sees it:
# Code Review
Current git status:
!git status
Recent changes:
!git diff --cachedWhen you run this command, git status and git diff execute first, and their output replaces the !command lines. Claude sees the actual current state of your repo, not a static instruction.
What does the !command syntax do inside a command file?
Arguments
Commands support $ARGUMENTS for accepting parameters:
---
description: Explain a concept
---
Explain the following concept in simple terms: $ARGUMENTSUsage: /explain what is a closure in JavaScript
Simple vs Complex Commands
Simple: One-step automation
---
description: Run tests with coverage
allowed-tools: Bash(npm test:*)
---
Run `npm test -- --coverage` and summarise the results.
Report any failing tests and coverage gaps.Complex: Multi-phase orchestration
---
description: Scan for bugs, triage, and fix
allowed-tools: Read, Glob, Grep, Task(code-fix-scout), Task(code-fixer-agent)
---
## Phase 1: Scanning
Launch 4 code-fix-scout agents in parallel:
- Scout 1: Logic and correctness errors
- Scout 2: Async and state issues
- Scout 3: Security vulnerabilities
- Scout 4: Error handling gaps
## Phase 2: Triage
Collect all scout reports. For each finding:
- Re-read the code to verify it's a real issue
- Score confidence 0-100
- Reject anything that would change UX
## Phase 3: Fix
For findings scoring ≥80, dispatch code-fixer-agent
with a precise brief describing what to change.The coordination capability is Claude's intelligence. Unlike a rigid CI pipeline, Claude can make judgment calls during triage, adapt to unexpected findings, and decide when to dispatch fixers in parallel vs sequentially. The command file is a recipe; Claude is the chef.
Why is Claude's intelligence important for command orchestration compared to a traditional CI pipeline?
Command Locations
Commands can live at three levels, with higher levels taking priority:
- Project-level:
.claude/commands/in your repo (highest priority) - Global:
~/.claude/commands/(middle) - Plugin: from marketplace cache (lowest)
This means you can override any plugin's command by creating a file with the same name in your project's .claude/commands/ directory.
The /commit-push-pr Pattern
Boris Cherny (creator of Claude Code) uses a custom /commit-push-pr command "dozens of times every day." It checks git status, formats code, creates a commit with a descriptive message, pushes, and opens a PR — all from a single slash command.
This is the "inner-loop automation" pattern: identify the sequence you repeat most often, and wrap it in a command. Common candidates: /test, /deploy, /review, /commit.
From Manual Steps to /deploy-staging
Most teams start with a mental checklist: run tests, build, deploy, post in Slack. After doing it manually a dozen times, it becomes a command:
---
description: Deploy current branch to staging
allowed-tools: Bash(bun run:*), Bash(npx vercel:*), Bash(curl:*)
---
# Deploy to Staging
1. Run `bun run test` — stop if anything fails
2. Run `bun run build` — stop if build errors
3. Deploy with `npx vercel --env staging`
4. Capture the preview URL from the output
5. Run a quick smoke test: `curl -s -o /dev/null -w "%{http_code}" <preview-url>`
6. Report the preview URL and smoke test resultThis is the natural progression: manual → mental checklist → slash command. If you find yourself doing the same 3+ steps repeatedly, it's time to make it a command.
When to Use Commands vs Skills
Commands = you decide when to run them (/deploy, /code-fix)
= Claude decides when to run them (auto-triggered based on context)
For expensive operations (like launching parallel agents), commands are the right choice — you want deliberate control over when they fire.
- Building monolithic commands. A 200-line command that does deployment, testing, notification, and cleanup is hard to debug and impossible to reuse. Break it into composable pieces:
/test,/deploy,/notify. - Forgetting
allowed-tools. Without it, Claude hits permission prompts mid-workflow, breaking automation. If your command runsnpm test, addBash(npm test:*)to allowed-tools. - Over-scripting logic. Commands are instructions, not scripts. "If test coverage is below 80%, fix the tests" is fine — Claude handles that judgment. Complex conditional branching turns markdown into a bad programming language.
Key Takeaway
Commands are the "buttons" in Claude Code's extension system. They're your primary tool for building custom workflows — wrapping repeatable sequences into a single invocation. The command file defines what to do; Claude's intelligence determines how.
