How to Create Custom Slash Commands for Claude Code: Complete Developer Guide
Claude Code custom slash commands are Markdown files with optional YAML frontmatter that accept arguments, execute bash snippets, and reference files, stored in .claude/commands/ or plugin directories.
Creating custom slash commands for Claude Code lets you automate repetitive tasks and standardize AI workflows across projects. According to the anthropics/claude-code repository, these commands are defined in simple Markdown files that the CLI discovers automatically from designated directories. This guide covers the file structure, configuration options, and deployment patterns implemented in the source code.
Where Custom Slash Commands Live
Claude Code scans three distinct locations to discover available commands, each serving different scopes of use.
| Location | Path | Discovery Method |
|---|---|---|
| Project-wide commands | .claude/commands/ |
Automatically scanned for *.md files |
| Personal commands | ~/.claude/commands/ |
Loaded for the current user across all sessions |
| Plugin commands | <plugin-root>/commands/ |
Registered via plugin manifest at .claude-plugin/plugin.json |
As documented in plugins/plugin-dev/skills/command-development/README.md, project-wide commands live in the repository's .claude/commands/ directory, making them available to anyone working on that codebase. Personal commands in ~/.claude/commands/ apply globally to your user environment. Plugin commands follow the structure defined in plugins/plugin-dev/skills/plugin-structure/references/component-patterns.md, where the manifest file explicitly registers command directories.
Command File Structure and Syntax
A slash command file is a standard Markdown document with optional YAML frontmatter delimited by --- lines. The frontmatter controls behavior and permissions, while the body defines the prompt executed by Claude.
Frontmatter Configuration
Valid fields are specified in plugins/plugin-dev/skills/command-development/references/frontmatter-reference.md:
| Field | Purpose | Example |
|---|---|---|
description |
Short description shown in /help |
description: Review recent changes |
allowed-tools |
Restricts available Claude tools | allowed-tools: Read, Bash(git:*) |
model |
Overrides conversation model | model: sonnet |
argument-hint |
Documents expected arguments | argument-hint: [file] [branch] |
Dynamic Content Injection
The prompt body supports three templating mechanisms:
- Positional arguments –
$1,$2, or$ARGUMENTSfor the entire input string - File references –
@path/to/fileinserts the file's contents - Bash execution –
!`git status`runs the command and injects stdout
Organizing Multiple Commands
For projects with many commands, use the component organization patterns defined in plugins/plugin-dev/skills/plugin-structure/references/component-patterns.md:
- Flat – All commands in a single
commands/folder (suitable for ≤ 15 commands) - Categorised – Separate folders like
admin-commands/andworkflow-commands/ - Hierarchical – Nested sub-folders requiring explicit paths in the plugin manifest
When using categorized or hierarchical layouts, you must specify each directory in the plugin manifest's commands array.
Registering Commands as a Plugin
To distribute commands as a reusable plugin, include a manifest at .claude-plugin/plugin.json. As detailed in plugins/plugin-dev/skills/plugin-structure/references/manifest-reference.md, only the name field is strictly required.
{
"name": "my-awesome-plugin"
}
Place the plugin directory in ~/.claude/plugins/ or a workspace-wide plugins/ folder. Claude Code loads registered commands automatically on startup.
Practical Implementation Examples
Minimal "Hello" Command
This example from plugins/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md demonstrates a complete plugin structure:
Directory layout:
my-hello-plugin/
├─ .claude-plugin/
│ └─ plugin.json
└─ commands/
└─ hello.md
plugin.json:
{
"name": "my-hello-plugin"
}
hello.md:
---
description: Prints a friendly greeting
argument-hint: [name]
allowed-tools: Read
---
# Hello Command
Hello, $1! 👋
> Executed at: {{now}}
Invoke with /hello Alice to output:
Hello, Alice! 👋
Executed at: 2025-01-15 14:30:22 UTC
Command with Arguments and Git Integration
This command accepts a path argument and executes git status:
---
description: Show Git status
allowed-tools: Bash(git:*)
argument-hint: [path]
---
# Git Status
Current repo status for `@${1}`:
!`git -C @${1} status --short`
$1captures the first argument (repository path)@${1}references the directory contents!`git -C @${1} status --short`executes git and inserts the output
Multi-Folder Plugin Structure
For complex plugins, reference multiple command directories in the manifest:
{
"name": "ci-tools",
"commands": [
"./commands",
"./admin-commands",
"./workflow-commands"
]
}
This configuration instructs Claude Code to scan all three directories for slash command definitions.
Summary
- Custom slash commands for Claude Code are Markdown files stored in
.claude/commands/(project),~/.claude/commands/(personal), or plugin directories - Command files use optional YAML frontmatter to configure
description,allowed-tools,model, andargument-hint - Dynamic content uses
$1for arguments,@filefor file references, and!`command`for bash execution - Plugins require a
plugin.jsonmanifest at.claude-plugin/plugin.jsonwith anamefield and optionalcommandsarray for multi-folder layouts - Reference implementations are available in
plugins/plugin-dev/skills/plugin-structure/examples/minimal-plugin.md
Frequently Asked Questions
Where does Claude Code look for custom slash commands?
Claude Code scans three locations: .claude/commands/ for project-specific commands, ~/.claude/commands/ for personal user commands, and <plugin-root>/commands/ for plugin-registered commands. According to plugins/plugin-dev/skills/command-development/README.md, the CLI automatically discovers any *.md files in these directories on startup.
What file extension must command files use?
Command files must use the .md extension. Claude Code specifically looks for Markdown files when scanning command directories, as the format supports both the optional YAML frontmatter configuration and the prompt body content.
Can I restrict which tools a slash command can use?
Yes. Use the allowed-tools field in the frontmatter to specify which Claude tools the command may invoke. For example, allowed-tools: Read, Bash(git:*) restricts the command to reading files and executing git commands. This is documented in plugins/plugin-dev/skills/command-development/references/frontmatter-reference.md.
How do I pass arguments to a custom slash command?
Use positional variables $1, $2, etc., in the command body to reference arguments passed by the user. Use $ARGUMENTS to capture the entire input string. You can also document expected arguments using the argument-hint frontmatter field, which displays in the /help output.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →