·Skills & Commands
How Claude Code skills work in 2026: the SKILL.md frontmatter, progressive disclosure, debugging skill triggers, packaging as plugins, and a real PR-review walkthrough with hooks and subagents.
Claude Code Skills: SKILL.md, Plugins, and Subagents — A Complete Guide (2026)
Claude Code Skills are Anthropic's progressive-disclosure capability packaging, shipped in 2025–2026: a skill is a directory with a SKILL.md whose frontmatter (≈30–100 tokens) loads at startup and whose body lazy-loads on demand. This guide is current as of August 2026 and covers: the full SKILL.md frontmatter, the three gates that decide whether a skill fires, the boundary between skills / plugins / subagents / slash commands, and a real PR-review walkthrough with hooks and a delegated subagent.
TL;DR
- Skill = a directory with a
SKILL.md; onlydescription(≈30–100 tokens) loads at startup, the body lazy-loads- August 2026:
description+when_to_useare concatenated with a hard cap of 1,536 characters; skills can carry hooks and be preloaded by subagents- Decision rule: model-invoked → skill; user-invoked → command; isolated context → subagent; cross-project distribution → plugin
- Coverage: frontmatter fields, three-gate trigger debugging, plugin packaging, PR-review walkthrough with subagent
What a skill actually is
A skill is a directory that contains a SKILL.md file. That's the whole required structure. The SKILL.md file has YAML frontmatter describing the skill, followed by a Markdown body with the detailed instructions, scripts, and examples.
The crucial design choice is progressive disclosure. When Claude Code starts a session, it loads only the frontmatter — the skill's name and description, roughly 30 to 100 tokens each. The full body of instructions is only read if and when Claude decides a user's request matches that skill. This is why you can register a large library of skills without bloating the context window on every turn: the cheap metadata is always present, and the expensive body loads lazily.
Think of a skill as a named, on-demand procedure that lives next to your code. Claude can invoke it when relevant, and you never pay for instructions you are not using.
The SKILL.md convention
A minimal skill looks like this:
my-skill/
└── SKILL.md
Inside SKILL.md, the frontmatter carries two required fields and a handful of optional ones:
---
name: commit-message-style
description: Writes Conventional Commits messages that match the team's changelog format. Use when the user wants to commit, or asks for a commit message.
allowed-tools: ["Bash(git log:*)", "Bash(git diff:*)"]
---
# Commit message style
When the user asks for a commit message:
1. Run `git diff --cached` to see what is staged.
2. Run `git log -5 --oneline` to match the recent message tone.
3. ...
The fields:
name(required) — the skill identifier, typically kebab-case. Keep it stable; other configs may reference it.description(required) — a short summary of what the skill does and when to use it. This is the only text Claude sees until it decides to load the skill, so it does double duty as a trigger. Aim for under 1,024 characters and include the situations where it applies ("Use when the user wants to…").allowed-tools(optional) — restricts which tools the skill may invoke, in the same format as elsewhere in Claude Code (for exampleBash(git log:*)). Omit it to inherit the session's default tool set.user-invocable(optional) — set totrueif the skill should also appear as an explicit slash command the user can call directly.
Beyond SKILL.md, a skill directory can hold anything that helps the instructions: reference files, templates, helper scripts, sample output. Keep the body of SKILL.md itself focused — a common guideline is to keep it under roughly 5,000 tokens, and to move long reference material into separate files the skill can read on demand.
Skills vs slash commands
The relationship between skills and slash commands confuses people at first, because they can overlap.
A slash command is an explicit, user-initiated action: you type /something and it runs. Historically these were defined as simple prompt files.
A skill is a capability the model can pull in automatically when a request matches its description. With user-invocable: true, a skill is also exposed as a slash command.
The practical takeaway: if you find yourself writing a slash command that is really "a reusable procedure Claude should know how to do," write it as a skill instead. Skills give you the automatic triggering for free, and the explicit invocation is an opt-in flag rather than the only entry point. Slash commands remain useful for quick, one-off prompts that do not need discovery logic.
Building a real skill
Let's make a skill that is genuinely useful: a consistent code-review checklist tailored to a repository. Create the directory under .claude/skills/ (project-local) or ~/.claude/skills/ (user-global):
.claude/skills/
└── review-checklist/
└── SKILL.md
.claude/skills/review-checklist/SKILL.md:
---
name: review-checklist
description: Runs a consistent code-review checklist against staged or recent changes before opening a PR. Use when the user asks to review code, prepare a PR, or check their own changes.
allowed-tools: ["Bash(git diff:*)", "Bash(git log:*)", "Read", "Grep"]
---
# Review checklist
Apply these checks to the current change set (`git diff` against the base branch):
1. **Tests** — are there new or updated tests for the behavior change? Flag pure additions with no test.
2. **Error paths** — does the new code handle failure cases, or only the happy path?
3. **Naming** — do new identifiers match the conventions in the surrounding module?
4. **Public surface** — does the change add to a public/exported API? If so, is it documented?
5. **Secrets and logs** — any credentials, tokens, or PII introduced into code or log lines?
Report findings as a short, ordered list grouped by file. End with one of: `LGTM`, `Minor fixes`, or `Block`.
To use it, just ask Claude Code in natural language: "Review my staged changes before I push." Because the description says to use it when the user asks to review code, Claude will load the skill and apply the checklist — no slash command required. You can also call it explicitly as /review-checklist if you set user-invocable: true.
Where skills live
Skills are loaded from several places, which lets you mix team-wide and personal capabilities:
- Project skills —
.claude/skills/checked into the repo, shared with everyone on the project. - User skills —
~/.claude/skills/for capabilities you want across all projects (your personal git aliases, your editor habits). - Plugin-provided skills — installed plugins can contribute skills alongside their other features.
This layering matters: put things that are project-specific (a commit style, a deploy procedure, a domain glossary) in the repo so the whole team gets them; put things that are yours (how you like PRs summarized) in your user directory.
Packaging and sharing
To share a skill beyond a single repo, the common path is a plugin. A plugin bundles one or more skills (plus optionally slash commands, hooks, and MCP servers) into a distributable unit that others install by name. Because each skill is just a directory with a SKILL.md, the barrier to extracting a skill into a shareable plugin is low: move the directory into a plugin layout, add a manifest, and publish.
A real, well-known example of this pattern is Superpowers (chartable on ClaudeMap), a community skill pack that packages dozens of vetted procedures — code review, test generation, migration helpers, and more — as composable skills you can drop into your own setup. Studying a pack like that is the fastest way to internalize how to scope a skill well: each one is small, has a sharp description, and delegates cross-cutting concerns to other skills rather than ballooning into a monolith.
When you package your own, the two questions to keep asking are: "Would a stranger understand when to use this from the description alone?" and "Could I split this into two skills that trigger more reliably?" Skills that try to do everything tend to trigger unreliably; skills that do one thing trigger like clockwork.
Debugging: why a skill does or doesn't trigger
Skills occasionally misfire — never firing, firing too often, or firing but being ignored. Three gates decide everything:
Gate 1: description truncation. Claude Code concatenates each candidate skill's description and when_to_use for display, with a hard cap of 1,536 characters (Claude Code Skills docs). Anything past the cap is silently dropped and the model never sees it. Fix: tighten the description, push synonyms into when_to_use.
Gate 2: model matching. At startup the listing is bounded by skillListingBudgetFraction (default ~1% of the context window); when the budget runs out, lower-priority skills collapse to "name-only." Fix: downgrade low-priority skills via skillOverrides, raise the listing budget, or trim other skills' descriptions.
Gate 3: context loading. Even when a skill triggers, the body has to be explicitly read for it to take effect. --debug makes Claude Code print each candidate skill's description-match score; /doctor lists the available skills, the current listing's share of the context budget, and whether any descriptions got truncated. Fix: run --debug + /doctor to find which gate is stuck.
Symptom → diagnosis → prescription:
| Symptom | Most likely cause | First prescription |
|---|---|---|
| Never fires | Description truncated / wrong keywords | Tighten description; push synonyms into when_to_use |
| Fires too often | Description too broad | Add negative examples; make verbs concrete ("commit with Conventional Commits" not "commit code") |
| Loads but ignored | Body not being read | Check user-invocable flag; verify context: fork is set correctly |
| Edits don't take effect | Top-level directory newly created | Restart the session; in-place edits to existing dirs are auto-reloaded |
Side-by-side: a weak description ("handle code") triggers unreliably; a sharp one ("Use when asking Claude to review staged changes, check Conventional Commits format, or run a pre-merge checklist") hits cleanly because the trigger phrases are concrete.
Skills vs plugins vs subagents vs slash commands: which one to use
The four primitives look interchangeable, but the decision rule is one sentence:
- Model-invoked → Skill
- User-invoked → Slash Command
- Isolated context / parallel → Subagent
- Distributed cross-project → Plugin
Four-way comparison:
| Dimension | Skill | Slash Command | Subagent | Plugin |
|---|---|---|---|---|
| Trigger | Model matches description | User types /name | User or model delegates Task | Installed into Claude Code |
| Context | Loaded into main session | Main session | Independent context window | Depends on contents |
| Namespace | Filesystem path | /name | Task agent id | plugin-name:skill-name |
| Typical use | Team review checklist, commit-message generation | Deploy, run tests | Isolated deep research, long-running tasks | Cross-team / external distribution |
Three common mistakes: (a) Using slash commands for repeatable flows is an anti-pattern — anything you do three or more times deserves to be a skill so you get auto-trigger. (b) Stuffing everything into one skill makes triggering unreliable — complex flows should chain skills or spawn subagents (Superpowers demonstrates 12+ skills coordinating). (c) "I want to distribute it cross-project" requires the plugin path (Claude Code Plugins docs define the manifest, marketplace.json, and /plugin install name@marketplace flow); a single extracted skill has a low barrier but still needs a manifest.
Subagent + skill nesting: a subagent's skills field injects the full SKILL.md (not just the description) into the subagent's context at startup, while a context: fork skill borrows a named agent's system prompt. Both behaviours are documented in Claude Code Subagents docs.
Walkthrough: build a team PR review skill
A real scenario: a .claude/skills/pr-review/ skill the whole team shares, with hooks, tightened allowed-tools, and a delegated subagent for security scanning.
Directory layout:
.claude/skills/pr-review/
├── SKILL.md # main entry
├── references/
│ └── checklist.md # review checklist, loaded on demand
├── scripts/
│ └── diff-summary.sh # called by PreToolUse hook
└── agents/
└── security-reviewer.md # delegated security-scanning subagent
SKILL.md (with hooks block):
---
name: pr-review
description: Use when reviewing staged or committed code changes, checking PR diffs against team conventions, or running a pre-merge checklist. Triggers on phrases like "review my changes", "check this PR", "pre-merge review".
allowed-tools: Read, Grep, Bash(git diff:*), Bash(gh pr diff:*)
disallowed-tools: Edit, Write
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "scripts/diff-summary.sh"
additionalContext: true
---
# PR Review Checklist
When this skill loads, walk through references/checklist.md systematically.
For security-sensitive patterns (auth, crypto, secrets), spawn a security-reviewer
subagent via Task tool with this prompt: "Scan the diff for OWASP Top 10 patterns."
Key design choices:
allowed-tools: Read, Grep, Bash(git diff:*)— read-only plusgit diffonly. A review skill should never write files — that's a "review skill waiting to cause an accident" (Claude Code Hooks docs: "Hooks can be defined directly in skill frontmatter and are scoped to the skill's lifecycle").disallowed-tools: Edit, Writeexplicitly denies file mutation.- The hooks block runs
diff-summary.shand pipes its output in viaadditionalContext— an Anthropic 2026 addition; the script's output is injected automatically when the skill fires. - The subagent
security-revieweris defined inagents/security-reviewer.mdwith its own context; it scans the diff and returns results to the main session.
Test triggers with three phrasings of the same ask:
- "review my staged changes" — should auto-trigger (description keywords match)
- "check if this PR is secure" — should trigger and delegate to subagent
- "run pr-review on branch feature-x" — explicit invocation under
user-invocable: true
If any one misses, run --debug to see match scores and adjust description.
Bundle into a plugin (for cross-project distribution): move the directory into pr-review-plugin/.claude-plugin/plugin.json, register it in marketplace.json, and use the renames compatibility map for existing installs. The Claude Plugins Official repo has full manifest examples.
Best practices
A few patterns we see hold up across mature skill libraries:
- Make the description earn its keep. It is the only thing loaded at startup and the only thing that decides whether the skill fires. Be specific about when to use it, not just what it does.
- Keep the body small and pointer-rich. Put long reference material in adjacent files and have the skill read them on demand, rather than inlining everything.
- Constrain tools deliberately. Use
allowed-toolsto keep a skill from doing more than it should — a review skill that can rewrite files is a review skill waiting to cause an accident. - Prefer many narrow skills over one big one. Triggering is more reliable when each skill owns a single intent.
- Test the trigger, not just the body. After writing a skill, try phrasing the request three different ways and confirm it loads. A skill whose body is perfect but never fires is worthless.
Start by extracting one procedure you repeat daily into .claude/skills/. Once you feel the relief of not typing those instructions again, you will start to see procedures worth packaging everywhere.
Frequently asked questions
What is a Claude Code skill?
A skill is a directory containing a SKILL.md file. The SKILL.md has YAML frontmatter (a name and a description) and a Markdown body of instructions. Claude Code loads only the frontmatter at startup and reads the full body only when a request matches the skill's description, so you can register many skills without bloating the context window.
What is the difference between a skill and a slash command?
A slash command is an explicit, user-initiated action. A skill is a capability the model can pull in automatically when a request matches its description. With user-invocable: true, a skill is also exposed as a slash command, but the automatic triggering is the skill's distinguishing feature.
Where do Claude Code skills live?
Skills load from several locations: project skills in .claude/skills/ (checked into the repo and shared with the team), user skills in ~/.claude/skills/ (personal, available across projects), and skills contributed by installed plugins. You can mix all three layers.
How large should a SKILL.md file be?
Keep the body of SKILL.md focused, commonly under roughly 5,000 tokens, and move long reference material into separate files the skill can read on demand. The description is the only thing loaded at startup, so it must earn its keep by specifying when to use the skill.
How can I tell when my skill fires, and where are the trigger logs?
Run Claude Code with --debug to see each candidate skill's description-match score, or invoke /doctor for the full available-skills list plus the current listing budget as a share of the context window. If a skill loads but stops influencing behaviour after the first response, strengthen the description and add synonyms in when_to_use. Top-level skill directories created mid-session require a restart; edits inside existing directories are picked up live.
What exactly is the relationship between skills and plugins, and can I ship a skill on its own?
A skill is the smallest loadable unit; a plugin is a distributable package that bundles skills, slash commands, agents, hooks, and MCP servers. You can absolutely ship a single skill — drop it in ~/.claude/skills/ for personal use or commit it to .claude/skills/ for team use. To share across projects or externally, wrap it in a plugin and register it in marketplace.json so it installs via /plugin install name@marketplace. The plugin name is an immutable slug; renames require a renames map entry to migrate existing installs.
Official references
- Claude Code Skills documentation
- Claude Code Plugins documentation
- Claude Code Subagents documentation
- Claude Code Hooks documentation
- Anthropic Skills example repository
- Claude Plugins Official (manifest and skill-bundle examples)
- Superpowers (obra/superpowers — multi-skill coordination reference)
- Agent Skills open specification
This guide is current as of August 2026. Skill schema and Claude Code action flags evolve; pin to a major version when bundling critical skills into a plugin.