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 $ARGUMENTS for the entire input string
  • File references@path/to/file inserts 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/ and workflow-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`
  • $1 captures 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, and argument-hint
  • Dynamic content uses $1 for arguments, @file for file references, and !`command` for bash execution
  • Plugins require a plugin.json manifest at .claude-plugin/plugin.json with a name field and optional commands array 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →