Guides

Custom slash commands in Claude Code, and how skills replaced them

Custom slash commands still work in Claude Code, but they're now the legacy format. Anthropic's docs are explicit: "custom commands have been merged into skills." A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and behave the same way — skills just add more.

The old format: .claude/commands/*.md

A slash command is a single Markdown file. The file name becomes the command name:

.claude/commands/fix-issue.md     # project: commit it, your team gets it
~/.claude/commands/fix-issue.md   # personal: every project on your machine
---
description: Fix a GitHub issue following our coding standards
---

Fix GitHub issue $ARGUMENTS following our coding standards.

Run /fix-issue 123 and Claude receives the text with $ARGUMENTS substituted for 123. Subdirectories namespace the command: .claude/commands/frontend/component.md becomes /frontend:component.

Why skills took over

A command file is just a prompt. It can't ship a reference doc, a script, or example output alongside it, and it can't be loaded automatically when Claude decides a task matches — only when you type the slash command yourself. Skills fix both:

Existing .claude/commands/ files keep working — nothing breaks. But the docs recommend skills for anything new.

Migrating a command to a skill

Move the file into its own directory and rename it:

.claude/commands/fix-issue.md
        ↓
.claude/skills/fix-issue/SKILL.md

The frontmatter and body carry over unchanged — same placeholders, same Markdown body:

---
name: fix-issue
description: Fix a GitHub issue following our coding standards. Use when
  asked to fix, close, or resolve a numbered issue.
disable-model-invocation: true
---

Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue with `gh issue view $ARGUMENTS`.
2. Reproduce the bug before changing anything.
3. Fix it, add a regression test, and reference the issue number in the commit.

Two frontmatter fields matter once a skill can trigger itself:

FieldEffect
descriptionWhat Claude reads to decide whether this skill matches the current task. Write it as "what it does + when to use it".
disable-model-invocation: trueKeep the old command behavior: only /fix-issue triggers it, never Claude on its own. Use this for anything with side effects, like deploys or file deletion.

For the full breakdown of writing a description that actually triggers, see the skills guide.

Arguments

Both formats support the same placeholders in the command body:

When to keep a plain command instead

Skills aren't strictly better for every case. A one-line command with no supporting files and no reason for Claude to ever invoke it automatically doesn't gain much from becoming a folder — a single Markdown file in .claude/commands/ is still fewer moving parts to review. Reach for a skill once you need any of: supporting files, automatic (non-slash) invocation, or the extra frontmatter controls like allowed-tools.

Related

If your commands or skills shell out and run PreToolUse hooks around them, the free hook builder is a quick way to write and test the matcher without a live Claude session.

Skip the setup: get the tested versions

Keelwork bundles 10 workflow skills, 5 tested safety hooks (including a full guard-bash and a secret scanner), 3 subagents and 5 CLAUDE.md templates, with a one-command installer that safely merges into your settings.

Get Keelwork — $24 →