Overview

Skills are named, user-invocable procedures that Claude Code can execute on demand. A skill packages a prompt, a set of tool calls, and optional hook sequences into a single slash command: /review, /deploy, /fix-lint. Store skills in .claude/skills/ or as a user-level library at ~/.claude/skills/. See claude-code for context on how skills fit into the broader workflow.

Lay out the skills directory under .claude

The canonical layout is flat. Each skill is a directory named after the command.

.claude/
└── skills/
    ├── review/
    │   └── SKILL.md
    ├── deploy/
    │   └── SKILL.md
    └── fix-lint/
        └── SKILL.md

The directory name is the slash command. /review loads .claude/skills/review/SKILL.md. Nested commands use path separators: .claude/skills/seo/audit/SKILL.md becomes /seo/audit.

User-level skills live at ~/.claude/skills/. They are always available regardless of project. Project-level skills override user-level on name collision.

Write SKILL.md as an executable instruction set

Each SKILL.md is the prompt Claude receives when the user invokes the skill. Write it as instructions, not documentation.

# /review
 
Review the staged diff for this project.
 
1. Run `git diff --staged` and read the output.
2. Check that every changed file passes `npm run lint`.
3. Summarize findings as a markdown checklist grouped by severity: blocking, warning, suggestion.
4. Do not suggest refactors outside the staged diff.
5. Do not modify any files.

Lead with the task. State the output format explicitly. Add explicit non-goals; skills without non-goals invite scope creep the same way prompts do. See prompt-design for the non-goals rule.

User-invocable skills replace repetitive prompt pasting

The value of a skill over a copy-pasted prompt is consistency. Every invocation uses the same instructions, the same tool sequence, and the same output format. Teams share skills via the project .claude/ directory; changes are reviewed in PRs like any other config.

Good skill candidates:

  • Repeated review procedures (/review, /security-review).
  • Phased setup sequences (/init, /session-start).
  • Format-then-lint pipelines (/fix-lint).
  • Deploy preflight checks (/deploy-check).

Bad skill candidates: one-off tasks you will never repeat; tasks that vary significantly by invocation. One-off tasks belong in the user message; variable tasks belong in parameterized prompts.

Pass arguments from the slash command to the skill

When the user types /review main..HEAD, the text after the command name is available to the skill as $ARGS.

# /review
 
Review the diff for `$ARGS` (default: `--staged` if empty).
 
Run `git diff $ARGS` and analyze the output.

Keep the interface narrow. Skills with more than two or three meaningful arguments are better expressed as an agent invoked with a brief. See claude-code-subagents for when to escalate to a subagent.

Choose a skill over a bare agent for repeatable, bounded tasks

The decision tree between a skill and a standalone agent:

A /deploy-check that runs the same five shell commands every time is a skill. A “build me this feature from this brief” task is an agent. Skills are cheap to invoke and cheap to reason about; agents are powerful but expensive.

Namespace skills to avoid collisions

User-level skills ship with generic names (/review, /init). Project skills should use project-specific names or subdirectories.

~/.claude/skills/review/        → /review (generic)
.claude/skills/myapp/review/    → /myapp/review (project-scoped)

Prefix project skills with the project name or domain when deploying skills users will also have globally. The project-level skill wins, but an explicit namespace makes the collision visible.