CoreMesh

Claude Code slash commands, custom commands, and how skills fit in

Which Claude Code slash commands are worth learning, how custom commands relate to skills, and why a command can fail to show up or run.

Claude Code slash commands are the things you type after / at the prompt. Some are built in (/skills, /doctor, /context, /reload-skills). Others are yours: a skill folder or a file in .claude/commands/ becomes a /name command you can run on demand.

The short version of the custom side: skills are the current way to build custom commands. A skill is a SKILL.md in a skills directory, and /name runs it. Old command files in .claude/commands/ still load, but if a skill and a command file share a name, the skill wins. I'd write new things as skills.

What slash commands are in Claude Code#

There are four kinds of thing you can type after /, and the / menu mixes them together:

  • Built-in commands, like /doctor or /skills. These ship with Claude Code. The full list lives on the commands reference page.
  • Bundled skills, like /verify, /simplify, and /code-review. They behave like commands but are skills under the hood.
  • Your own skills and command files, from the locations covered below.
  • Plugin skills and MCP prompts. Plugin skills are namespaced as /plugin-name:skill-name, and MCP prompts show up as commands too.

That last point explains most confusion. When people ask about "slash commands vs skills," they're usually looking at one menu that holds both.

Built-in commands worth knowing#

I'm not going to list every built-in here, because the reference page does that better and changes with releases. These are the ones the documentation ties to day-to-day setup problems, so they're the ones I'd learn first.

Command What it does
/skills Lists the skills Claude Code loaded. Synced claude.ai skills appear under claude.ai sync, and a note explains any synced skill that lost its short name.
/reload-skills Picks up skills in a top-level skills directory that didn't exist when the session started.
/reload-plugins Applies changes to hooks/, .mcp.json, agents/, and output-styles/ in a skill folder that's also a plugin.
/context Shows what's loaded. Synced skills are grouped under claude.ai sync here too.
/doctor The in-session setup checkup, which can also apply fixes.
/import Brings configuration from other coding agents into Claude Code. Takes --dry-run and --yes.
/login Signs in. Skill syncing only starts after a restart if you sign in mid-session.
/usage Usage info. /cost is a built-in alias for it.
/code-review Bundled skill. /review is its alias.
/verify and /simplify Bundled skills. /verify records a recipe at your repo root as a project skill.

Two things from that table matter later. Aliases are separate names, and overriding a command doesn't override its aliases.

Outside a session, there's also a shell-side counterpart for a few of these. claude doctor prints read-only diagnostics without starting a session, and claude import codex --dry-run starts a session that runs /import. Both are in the CLI reference.

How to create a custom slash command#

The smallest version is a skill folder with a SKILL.md inside. Skills load from four places:

Location Path
Enterprise Set by your organization
Personal ~/.claude/skills/
Project .claude/skills/ in the repo
Additional directory .claude/skills/ inside a directory you pass with --add-dir

Here's a project skill. Put it at .claude/skills/release-notes/SKILL.md:

markdown
---
name: release-notes
description: Draft release notes from the commits since the last tag
---

Look at the commits since the most recent git tag.
Group them into Features, Fixes, and Internal.
Write the notes as a short markdown list.

Type /release-notes and it runs. The frontmatter name field sets the command name. If you leave it out, the folder name is what gets used for the command. For the exact precedence between the two, see "How a skill gets its command name" on the slash commands page.

You don't need to restart. Claude Code watches the skill directories (except in bare mode) and picks up adds, edits, and removals in the running session. The exception is a top-level skills directory that didn't exist when the session began. For that, run /reload-skills, and run it again after each later change there.

Keep Claude from running it on its own#

Some skills should only fire when you type the command. A deploy skill is the obvious case. Add disable-model-invocation: true to the frontmatter:

markdown
---
name: deploy
description: Deploy the current branch to staging
disable-model-invocation: true
---

Run the staging deploy steps for this repo.

This is documented as a way to stop Claude from invoking a skill. It has a side effect worth knowing: the commit-time check described below only applies to skills Claude can invoke.

One gap: the portion of the docs I worked from doesn't cover passing arguments to a command. If you need that, read the full slash commands page rather than guessing at a placeholder syntax.

Slash commands vs skills#

The two overlap enough that the old distinction mostly doesn't matter in practice:

  • A file in .claude/commands/ still works as a command.
  • A skill with the same name as that file wins.
  • Both can be invoked by name with /name.
  • Skills get extras that a bare command file doesn't have in the docs: live change detection on SKILL.md, enterprise and personal scoping, and the disable-model-invocation control.

My advice: leave existing command files alone until you have a reason to touch them, and write anything new as a skill. If you rename a command file into a skill folder with the same name, nothing breaks, because the skill simply takes over.

Which command runs when names collide#

This is where "my command does the wrong thing" comes from. The documented rules:

Same name in Which one runs
Enterprise, personal, project Enterprise over personal, personal over project
Your skill and a bundled skill Your skill replaces the bundled command, but not its aliases
Your skill and a built-in command In a local terminal session, your skill replaces the built-in, but not its aliases
A skill and a .claude/commands/ file The skill
Plugin skill and anything else Both load, since the plugin one is /plugin-name:skill-name

The docs give two concrete cases. With deploy in both ~/.claude/skills/ and the project's .claude/skills/, /deploy runs the personal one. A project usage skill replaces /usage, but /cost still runs the built-in.

Here's that logic as a runnable sketch, so you can try your own combinations. It only models the enterprise/personal/project ordering and the skill-over-command-file rule from the table.

python
ORDER = ['enterprise', 'personal', 'project']

def winner(where):
    # where: set of places the same name exists
    for place in ORDER:
        if place in where:
            return place + ' skill'
    if 'commands-file' in where:
        return '.claude/commands file'
    return 'nothing'

cases = [
    {'personal', 'project'},
    {'project', 'commands-file'},
    {'commands-file'},
    {'enterprise', 'personal', 'project'},
]
for c in cases:
    print(sorted(c), '->', winner(c))

Slash commands not showing or not working#

Work through these in order. They're all taken from documented behavior.

  1. You made a new top-level skills directory mid-session. Claude Code wasn't watching it. Run /reload-skills.
  2. Another command took the name. A built-in, bundled skill, plugin skill, file in .claude/commands/, or MCP prompt can hold the short name. Run /skills and read the note under the list.
  3. It's a synced claude.ai skill that lost its short name. Then it only runs as /anthropic-skills:<name>. A local deploy and a synced deploy means /deploy runs the local one.
  4. You used a reserved name. anthropic-skills, and anything inside that namespace, is reserved. A skill folder, frontmatter name, or .claude/commands/ entry using it doesn't load, and a startup notice names the first thing to rename.
  5. An MCP server is named anthropic-skills. Its tools work, but its prompts don't appear as commands. Rename the server.
  6. Skill changes in a plugin folder. Changes to hooks/, .mcp.json, agents/, and output-styles/ need /reload-plugins. Live detection only covers SKILL.md text.
  7. You're in a cloud session, Cowork, or a routine. These don't read ~/.claude/skills/ on your machine. Commit the skill to the repo's .claude/skills/, or enable it for your claude.ai account. Desktop scheduled tasks run locally, so they do load personal skills.
  8. Case or look-alike names. Name comparison ignores case, spacing, and invisible characters, so Commit and commit count as the same. A look-alike letter from another alphabet counts as different.

Synced skills also behave differently from local ones. In sessions on your machine, a synced skill's ! command lines and @ references reach Claude as literal text instead of running. If a skill you downloaded behaves oddly, check that first.

Common mistakes#

  • Overriding a command and expecting the alias to follow. It doesn't. Your usage skill won't catch /cost.
  • Editing files under ~/.claude/skills/synced/. Syncing only downloads. Your edits aren't saved to claude.ai, and a later sync can overwrite or remove them. Change the skill on claude.ai.
  • Assuming plugin, bundled, or claude.ai skills trigger the commit check. They don't. Only skills from enterprise, personal, project, or additional-directory locations (or a .claude/commands/ file) count.
  • Using disable-model-invocation: true and expecting commit checks. If Claude can't invoke the skill, it doesn't get the instruction.
  • Expecting sync in an API-key session. Syncing needs a claude.ai sign-in from /login and feature flag fetching. Sessions using an API key, Bedrock, bare mode, or --safe-mode don't sync.

Run your checks before each commit#

There's one place where a command name has a special effect. If a skill named verify or simplify is in place when a session starts, Claude Code's commit instructions tell Claude to run it right before each commit, except for changes to docs or tests. It needs Claude Code v2.1.286 or later, and includeGitInstructions can't be turned off. The recipe that /verify writes at your repo root is a project skill, so it qualifies. The bundled /verify and /simplify don't.

Quick reference#

  • Custom command = SKILL.md in ~/.claude/skills/<name>/ or .claude/skills/<name>/.
  • Old .claude/commands/ files still work; a same-named skill beats them.
  • Name comes from frontmatter name; set disable-model-invocation: true to keep Claude from invoking it.
  • Edits are picked up live. A brand-new top-level skills directory needs /reload-skills.
  • Missing command? Run /skills and read the note under the list.
  • Enterprise beats personal, personal beats project.
  • Overriding a command never overrides its aliases.
  • Cloud and Cowork sessions don't read ~/.claude/skills/.

Quick answers

Are Claude Code custom slash commands the same as skills?

Close enough. A skill folder with a SKILL.md becomes a /name command, and old .claude/commands/ files still work. If a skill and a command file share a name, the skill runs.

Why is my Claude Code slash command not showing?

Most often the skills directory is brand new, so run /reload-skills. Otherwise another command may own the name, so run /skills and read the note under the list.

Where do I put a custom slash command?

For yourself, use ~/.claude/skills/<name>/SKILL.md. For a repo, use .claude/skills/<name>/SKILL.md. Enterprise and --add-dir locations also load.

Can I stop Claude from running a skill on its own?

Yes. Add disable-model-invocation: true to the skill's frontmatter. You can still run it by typing the command.

Indra Wijaya

Builds and runs AI agents, bots and content pipelines, and writes down what works and what broke.

About · GitHub · RSS

Keep reading

New notes, no spam.

One post at a time, only when there's something worth reading. Follow in any feed reader.

Subscribe via RSS