Claude Code skills vs. slash commands: what changed
The short answer: custom commands were merged into skills. A file at
.claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md can both create
/deploy, and existing command files still work.
That sounds like a simple rename. It is not quite one. Slash commands are the visible way you invoke something; skills are now the more capable packaging model behind custom workflows. A skill can carry supporting files, declare how it should be invoked, and load automatically when the task matches.
If you are deciding what to build today, start with a skill. Keep an existing command file when it works, migration would add no value, and you have a reason not to disturb a known workflow.
The terms that get mixed together
Claude Code has three different things that can look similar in the / menu:
| Thing | Who provides it | What it does | Example |
|---|---|---|---|
| Built-in command | Claude Code | Runs fixed product behavior | /help, /compact |
| Bundled skill | Claude Code | Gives Claude a prompt-based workflow | /debug, /code-review |
| Your skill or legacy command | You or your team | Packages your instructions and resources | /deploy, /release-notes |
The mistake is assuming a slash name tells you how the item executes. It does not. Most built-in commands run fixed logic. A bundled or custom skill gives the model detailed instructions and lets it use available tools. That difference affects review, permissions, runtime, and what can go wrong.
The two paths, side by side
An older custom command can be a single Markdown file:
.claude/commands/deploy.md
A skill lives in a directory and has a required instruction file:
.claude/skills/deploy/
└── SKILL.md
Both expose /deploy. If both are present, the skill takes precedence. Claude Code still supports
command-file frontmatter, but it recommends skills because they can also include supporting files.
That extra folder is useful only when the workflow needs it. A release skill may include a checklist, a changelog template, and a script that gathers commits. A two-line command that formats the current branch name does not need an elaborate directory tree merely to look modern.
Skills can be automatic or manual
The practical improvement is discovery. Claude can load a skill when its description matches the
request, or a person can invoke it directly with /skill-name. Put the capability and trigger in the
description, then keep the body focused on what should happen after activation.
For a workflow that should never run because a casual request happened to sound similar — deployment,
database cleanup, publishing, or a long test suite — make it manual-only. Claude Code supports
disable-model-invocation: true in skill frontmatter for that case.
The contrast is useful:
---
name: summarize-changes
description: Summarizes uncommitted changes and flags risky areas. Use when a user asks what changed or requests a diff review.
---
That skill benefits from natural triggering. A deployment skill should say what it requires, but wait
for /deploy so a general question about deployment cannot start a consequential procedure.
A small migration example
Suppose this legacy command is working:
<!-- .claude/commands/release-notes.md -->
Create release notes from the changes on this branch. Group them under Added, Changed, and Fixed.
Do not include internal maintenance.
Move it when you need shared examples or stricter behavior:
<!-- .claude/skills/release-notes/SKILL.md -->
---
name: release-notes
description: Draft public release notes from a branch diff. Use when preparing a release note or changelog entry.
disable-model-invocation: true
---
## Required inputs
- A diff or a defined commit range.
- The public product terminology in `references/terms.md`.
## Process
1. Exclude internal maintenance and unannounced work.
2. Group reader-visible changes under Added, Changed, and Fixed.
3. Flag ambiguous changes instead of guessing.
4. Return a draft for human approval; do not publish it.
The migration did not make the prose smarter. It made the workflow inspectable, gave it a place for focused reference material, and defined a stop condition. If none of those benefits are needed, leave the command as it is.
Arguments, tools, and sharing change the choice
Skills can accept arguments, use dynamic context, pre-approve narrowly scoped tools, and run in a subagent context. Those are powerful features, so they deserve the same review as application code. They are not a reason to grant a skill broad shell or network access by default.
Where the files live also changes who inherits the behavior:
| Scope | Location | Use it for |
|---|---|---|
| Personal | ~/.claude/skills/<name>/SKILL.md |
A workflow you use across your own projects |
| Project | .claude/skills/<name>/SKILL.md |
A reviewed team workflow that belongs with the repository |
| Plugin | <plugin>/skills/<name>/SKILL.md |
A versioned bundle shared across projects or teams |
Project skills are especially valuable because their instructions can be committed, reviewed, and
updated with the code they affect. A personal skill with the same name can override a project skill,
however, so check /skills when behavior is unexpectedly different on one machine. Plugin skills are
namespaced as /plugin-name:skill-name, so they never collide with the other two.
Common migration mistakes
The first is copying a legacy command into SKILL.md word for word and calling the migration done.
That preserves compatibility, but it does not use the structure that justified the move. Add only the
resources that the command repeatedly needed: a reference glossary, a checked template, or a small
script with explicit inputs and outputs. More files are not more capability.
The second is allowing every skill to trigger itself. A broad description such as “helps with releases” will eventually activate while someone is merely asking a question about releases. Name the work, inputs, and outcome instead; reserve explicit invocation for operations that are expensive, mutating, or require a final human decision.
The third is treating allowed-tools as documentation. It can affect the permission flow, so reduce
the list to the tools the workflow actually needs. A release-notes skill that needs to read a diff has
no reason to receive a general network or deployment capability. Test the refusal path as well as the
happy path: missing inputs should produce a question or a clear stop, not a resourceful guess.
When to keep a command — and when to migrate
Keep the command file when it is tiny, stable, manual, and has no supporting material. Migrate when the same command has acquired a checklist, examples, scripts, safety rules, or a need for automatic discovery. Start a new workflow as a skill when it is a reusable procedure rather than a one-line shortcut.
Do not migrate only because a blog post called commands obsolete. Compatibility is still there. The useful modernization is giving recurring work a clear package, an accurate trigger, and a reviewable home — not changing a path for its own sake.
For the broader model, read what AI agent skills are and then how to create one. If you are moving existing routines, test one natural trigger, one direct invocation, one nearby non-trigger, and one missing-input case.
Next step: Explore Claude commands on LLM Mart, then turn the one command that keeps growing new rules into a small, reviewable skill.
Sources
Comments (0)
Sign in to join the conversation.
No comments yet.