What a skill is
A skill is a folder with a SKILL.md file in it. The file holds instructions. Claude Code loads it when it is relevant, or you invoke it directly by typing /skill-name.
That is genuinely the whole mechanism. What makes it worth understanding is a property that is easy to miss: a skill's body loads only when the skill is used.
Compare that to CLAUDE.md, which is loaded into every session, every request, forever. A 200-line deployment procedure in CLAUDE.md is paid for on every single message you send, including the ones about CSS. The same procedure as a skill costs almost nothing until the day you deploy.
One more thing worth knowing up front: custom commands and skills are now the same system. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy. Existing commands/ files keep working. Skills add a folder for supporting files, frontmatter for controlling invocation, and the ability for Claude to load them automatically.
When something should become a skill
Two signals, and they are reliable:
You keep pasting the same thing. The same checklist, the same multi-step procedure, the same set of constraints. If you have typed it three times, it is a skill.
A section of CLAUDE.md has grown into a procedure. CLAUDE.md should hold facts and rules — what this project is, what must never happen, what to run before finishing. The moment a section becomes steps to follow when doing X, it has outgrown the file. Move it to a skill and your CLAUDE.md gets shorter, which makes everything left in it work better.
That second one is the more valuable observation. Length is the main failure mode of a CLAUDE.md, and skills are the pressure valve.
Writing your first one
Two steps.
mkdir -p ~/.claude/skills/summarize-changes
Then ~/.claude/skills/summarize-changes/SKILL.md:
---
description: Summarise uncommitted changes for a commit message or PR
description. Use when work is finished and needs writing up.
---
Run `git diff` and `git status` to see what actually changed.
Write a summary with:
- One line saying what this change does, in the imperative
- What changed and why, grouped by concern rather than by file
- Anything a reviewer should look at closely
- Anything you could not verify
Describe the change, not the process of making it. Nobody needs to know
which file you opened first.
That is a working skill. Type /summarize-changes and it runs.
The directory name becomes the command. The description is what Claude reads when deciding whether to load it on its own — which is why it should say when to use this, not just what it does.
Where skills live, and which one wins
| Scope | Path | Applies to |
|---|---|---|
| Personal | ~/.claude/skills/<name>/SKILL.md |
All your projects |
| Project | .claude/skills/<name>/SKILL.md |
This project — commit it |
| Plugin | <plugin>/skills/<name>/SKILL.md |
Wherever that plugin is enabled |
Precedence has one result that surprises people: with a deploy skill in both ~/.claude/skills/ and the project's .claude/skills/, the personal one runs. Your own skill shadows the team's. If a teammate reports that the project's /deploy is doing something odd, check whether they have a personal skill of the same name.
Plugin skills sidestep this entirely by being namespaced — my-plugin/skills/deploy/SKILL.md becomes /my-plugin:deploy and coexists with a project deploy rather than fighting it.
Two further behaviours worth knowing:
Project skills load from the start directory and every parent up to the repo root, so starting Claude in a subdirectory still picks up skills defined at the top.
Nested skills load lazily. Skills in a .claude/skills/ below your working directory are not available at startup. They become available the first time Claude reads or edits a file in that subdirectory. In a monorepo this is the feature that lets a package carry its own skills — but until Claude touches that package, those skills do not appear in autocomplete and cannot be invoked by name.
Claude Code also watches skill directories and picks up edits within the session, without a restart. If you create a top-level skills directory that did not exist when the session started, restart so it can be watched.
Frontmatter that changes behaviour
Every field is optional; only description is really recommended. These are the ones that do something you will notice:
| Field | Effect |
|---|---|
description |
How Claude decides to load it. Put the key use case first — this text is truncated at 1,536 characters in the listing. |
when_to_use |
Trigger phrases and example requests. Counts toward the same 1,536-character cap. |
disable-model-invocation |
true means only you can run it, by typing /name. Use for anything with consequences. |
user-invocable |
false means only Claude runs it. For background knowledge you should not invoke directly. |
allowed-tools |
Tools pre-approved for the turn that invokes this skill. The grant clears on your next message. |
disallowed-tools |
Tools removed while the skill is active. |
model / effort
|
Override for the turn. Useful for an expensive audit or a cheap mechanical pass. |
paths |
Globs limiting when the skill auto-loads. A CSS skill that only wakes for stylesheets. |
context: fork |
Run the skill in a forked subagent instead of the main thread. |
argument-hint |
Autocomplete hint, e.g. [issue-number]. |
The pair worth adopting as a habit is disable-model-invocation and allowed-tools. The first stops a consequential skill from firing because a description looked relevant. The second stops a routine skill from generating a permission prompt on every step, which is what trains people to approve without reading.
Passing arguments
$ARGUMENTS captures everything typed after the skill name:
---
description: Explain what a file does and what depends on it
argument-hint: [path]
---
Explain `$ARGUMENTS`: what it does, what calls it, what it calls, and
what would break if it changed. Cite line numbers.
Then /explain src/auth/session.ts.
For several arguments, name them with the arguments field and reference them as $name. That is clearer than positional splitting once you have more than one.
Supporting files, and why the body is lazy
A skill is a folder, so it can hold more than SKILL.md. Reference material, templates, scripts, examples — all of it sits alongside, and none of it enters context until the skill actually runs and Claude reads it.
This is what makes skills the right home for genuinely long material. A 40-page style guide as an import in CLAUDE.md is 40 pages on every request. The same guide in a skill folder is free until the day someone asks about style.
The general principle: rules that must always apply belong in CLAUDE.md; procedures and reference material belong in skills. Getting that split right is most of what keeps a project's context lean.
Running a skill in a subagent
Set context: fork and the skill runs in a forked subagent rather than your main thread:
---
description: Full technical SEO audit of this project
context: fork
agent: general-purpose
model: opus
---
Audit indexability, canonicalisation, status codes, sitemap contents,
metadata uniqueness, heading hierarchy, structured data, and internal
linking.
Evidence for every finding — a file and line, or the actual response.
Rank by real impact. Say what you could not check.
Do not invent search volumes, difficulty scores, or traffic estimates.
"Not measured" is a correct answer.
The audit reads a great deal and returns a report. Forking keeps all that reading out of your session. By default a forked skill runs in the background; set background: false to wait for the result in the same turn.
This is where skills and subagents meet: the skill is the procedure, the subagent is the isolation.
Skill, CLAUDE.md, or subagent?
| Use | For | Cost |
|---|---|---|
CLAUDE.md |
Facts and rules that must always hold | Every request, forever |
| Skill | A procedure you run sometimes | Only when used |
| Subagent | Work that should happen in its own context, with its own tool limits | Only when delegated |
The test: would it be wrong for Claude to not know this right now? If yes, it is a CLAUDE.md rule. If it is only relevant while doing a particular job, it is a skill. If the job would flood your context or needs tools locked down, put the skill in a subagent.
There is a fourth answer for anything mechanical that should happen every time regardless of whether it was invoked: a hook.
Four skills worth writing
/check — the finishing procedure
Run the type checker, the linter, the tests, and the build; show the real output; state what was not verified. The single most useful skill in most projects, because it turns "done" from a claim into a procedure.
/review — with context: fork
A review that runs in a fresh context will not defend the code it is reviewing.
/ship — with disable-model-invocation: true
The deploy sequence, in order, with the rollback written down. Model invocation off, because a deploy should never fire because a description looked relevant.
/audit-a11y — with paths
Scoped to your template and component globs so it only wakes for UI work.
Where skills go wrong
A description that says what, not when
"Deployment skill" tells Claude nothing about when to reach for it. "Use when deploying to production or when asked to ship" does.
Dumping CLAUDE.md into a skill and calling it done
Rules that must always apply do not work as a skill, because the skill might not load. Move procedures; keep rules.
Consequential skills left model-invocable
Anything that deploys, deletes, migrates, or spends money should require you to type it.
One giant skill
A skill covering deployment, testing, and review will be loaded for all three and is right for none. Split by job.
Forgetting personal skills shadow project ones
The commonest confusing bug in this system, and invisible until you check both directories.
Where to go next
Skills package a procedure. Subagents package who runs it and with what tools, and plugins package both so a team can install them in one step. The always-on layer beneath all three is a production CLAUDE.md. For the procedures themselves, the prompt library is a ready supply of skill bodies, and the complete website workflow shows where each one fires.
Sources and further reading
-
Claude Code: skills —
SKILL.mdformat, locations, precedence, and the full frontmatter reference - Agent Skills — the open standard skills follow
-
Claude Code: memory — what belongs in
CLAUDE.mdinstead