How to Write a Claude Skill (the Progressive-Disclosure Way Anthropic Now Recommends)
Read time: ~7 minutes. Key facts:
- A skill is a folder with one file:
<skill-name>/SKILL.md— personal skills live in~/.claude/skills/, project skills in the repo’s.claude/skills/.- Frontmatter has exactly two required fields:
nameanddescription(plus optional ones likeallowed-toolsanddisable-model-invocation).- Skills use progressive disclosure in three layers: at session start Claude sees only every skill’s
name+description; it loads the full SKILL.md only when the skill looks relevant; extra files load only if the skill points to them.- That makes the
descriptionthe single highest-leverage line you write — it’s the only thing deciding whether your skill ever fires.Sourcing note: the loading model and frontmatter fields are from Anthropic’s Agent Skills docs and Claude Code skills docs. Directory layout and a real frontmatter example were verified on a live setup (49 personal skills under
~/.claude/skills/) while writing this. Links at the bottom.
Anthropic’s new context-engineering rules tell you to gut your CLAUDE.md and push situational instructions into skills. Good advice — but it leaves the obvious question: how do I write one, and why doesn’t it blow up my context? The answer is a loading model most people never see. Here’s how skills actually work and how to write one that fires when it should.
1. A skill is one file in one folder
The whole format:
~/.claude/skills/
my-skill/
SKILL.md # the only required file
reference.md # optional extra files, loaded on demand
- Personal skills (available in every project):
~/.claude/skills/<skill-name>/SKILL.md - Project skills (shared with the repo, committed to git):
.claude/skills/<skill-name>/SKILL.md
That’s it. No registration, no config file listing them — dropping the folder in makes the skill available.
2. The frontmatter: two fields that matter
SKILL.md opens with a small YAML block. Only name and description are required:
---
name: web-design-guidelines
description: Audit existing UI code against the Vercel Web Interface Guidelines (100+ rules covering accessibility, focus, forms, animation, typography, performance, i18n, hydration). Use when user asks "review my UI", "check accessibility", "audit this component", "lint my UX", or "check against best practices". This is a REVIEW skill, not a generation skill — feed it files/components and it returns terse `file:line` findings.
---
<!-- the body: your actual instructions -->
(That’s a real skill’s frontmatter from a live setup — note how much work the description does.)
name— lowercase, hyphenated, concise. Matches the folder name.description— what it does and when to use it. See §4; this is the whole ballgame.- Optional fields include
allowed-tools(restrict which tools the skill may use) anddisable-model-invocation(stop Claude from auto-triggering it, so it only runs when you invoke it explicitly).
Everything after the frontmatter is just Markdown — your instructions, in whatever structure helps.
3. Why skills are nearly free: three-layer progressive disclosure
This is the part the format hides, and it’s why “move it into a skill” is cheaper than “put it in CLAUDE.md”:
- Layer 1 — metadata, always loaded. At session start, Claude sees only the
nameanddescriptionof every available skill. Not the bodies. Fifty skills cost you fifty short description lines, not fifty documents. - Layer 2 — the full SKILL.md, loaded on relevance. When Claude decides a skill matches what you’re asking, it reads the whole file.
- Layer 3 — extra files, loaded on demand. Anything the skill references (
reference.md, examples, scripts) loads only if it’s actually needed.
Contrast that with CLAUDE.md, which is loaded every turn, every session whether relevant or not (the per-turn tax we measured in Claude Code’s token overhead). A 5,000-token instruction block costs 5,000 tokens always in CLAUDE.md; as a skill it costs ~1 line until the moment it’s useful.
Implication: you can afford many skills. What you can’t afford is many always-on instructions.
4. The description is the whole ballgame
Because Layer 1 is all Claude sees upfront, your description is the only thing that decides whether the skill ever fires. A perfect skill body with a vague description never runs.
Write it with three things in it:
- What it does — concretely. (“Audit UI code against 100+ accessibility/focus/form rules.”)
- When to use it — including the phrasings a user would actually type. (“Use when the user asks ‘review my UI’, ‘check accessibility’, ‘audit this component’…”)
- What it is not — the boundary that prevents misfires. (“This is a REVIEW skill, not a generation skill.”)
# ❌ too vague — will rarely trigger
description: Helps with design.
# ✅ triggers reliably
description: Audit existing UI code against accessibility, focus, form, and
typography rules. Use when the user asks to "review my UI", "check
accessibility", "audit this component", or "lint my UX". REVIEW only —
does not generate new components.
Think of it as the matching key, not a summary. Include the literal trigger phrases.
5. Split long skills across files
Anthropic’s guidance is explicit: for a long skill, divide it into many files and split them out, rather than one giant SKILL.md. Keep SKILL.md as the entry point — what this is, when to use it, the core steps — and push the deep detail into siblings the skill points to:
my-skill/
SKILL.md # entry point: overview + core workflow
api-reference.md # loaded only when the task needs the API details
examples.md # loaded only when examples are relevant
This keeps Layer 2 small. If your SKILL.md is thousands of tokens, every invocation pays for all of it — even when the task only needed one section.
6. Write one: a worked shape
A solid skill body follows the same skeleton:
---
name: release-notes
description: Draft release notes from merged PRs since the last tag. Use when
the user asks to "write release notes", "draft a changelog", or "summarize
what shipped". Produces markdown grouped by feature/fix/chore.
---
## When to use this
Use after a release branch is cut, before publishing the GitHub release.
## Steps
1. `git log <last-tag>..HEAD --oneline` to get the merged commits.
2. Group by conventional-commit prefix (feat / fix / chore).
3. Write one user-facing line per entry — what changed for the user, not the diff.
4. Flag anything breaking at the top under **Breaking changes**.
## Conventions
- Skip internal refactors unless user-visible.
- Link PR numbers as `(#1234)`.
See `examples.md` for a formatted sample.
Note what it does not do: it doesn’t restate general engineering advice, and it doesn’t over-prescribe. Per the Claude 5 context rules, encode your team’s particular opinions and gotchas — not things a competent model already knows.
7. Skills vs CLAUDE.md vs subagents
Quick routing so you put things in the right place:
| Put it in… | When |
|---|---|
CLAUDE.md | Always-relevant repo facts: what this repo is, the non-obvious gotchas |
| A skill | Situational, task-specific procedure — only needed sometimes |
| A subagent | Work that should run in its own context window (big searches, parallel tasks) |
The failure mode is putting situational procedures in CLAUDE.md: you pay for them every turn, and they compete with the actual task for attention.
8. Test that it fires
Two checks after you write one:
- Trigger test: start a fresh session and phrase a request the way a real user would. If the skill doesn’t fire, the
descriptionis too vague — add the literal phrasings. - Rightsize it: run
/doctorin Claude Code, which Anthropic ships specifically to rightsize your skills andCLAUDE.mdagainst the current guidance.
If a skill should never auto-fire (a destructive or expensive workflow), set disable-model-invocation so it only runs when explicitly invoked.
The takeaway
A Claude skill is just <name>/SKILL.md with two required frontmatter fields — dropped into ~/.claude/skills/ (personal) or .claude/skills/ (project). It’s cheap because of three-layer progressive disclosure: only name + description load at session start, the body loads when relevant, extra files load on demand. So write many small skills instead of one big CLAUDE.md — and spend your effort on the description, which is the only thing deciding whether the skill ever fires: say what it does, when to use it (with literal trigger phrases), and what it isn’t. Split long skills across files, keep CLAUDE.md for always-true facts, and run /doctor to check your sizing.
For the strategy behind this shift, see the new rules of context engineering for Claude 5 models; for the cost math, reducing Claude Code’s token overhead.
Sources
- Agent Skills overview — Anthropic docs — SKILL.md format, required
name/descriptionfrontmatter, optional fields (allowed-tools,disable-model-invocation), progressive-disclosure loading (metadata at startup → full SKILL.md on relevance → linked files on demand) - Extend Claude with skills — Claude Code docs — personal (
~/.claude/skills/) vs project (.claude/skills/) locations, discovery without registration - The new rules of context engineering for Claude 5 generation models — Anthropic — skills as “lightweight guides,” splitting long skills into many files, encoding team-particular opinions,
/doctorfor rightsizing - Directory layout and the example frontmatter were verified on a live Claude Code setup (49 personal skills under
~/.claude/skills/, Claude Code 2.1.220) on July 27, 2026. Confirm optional frontmatter fields against the live docs, as the schema evolves.