Claude Code Skills: How to Write a SKILL.md (5 Copy-Paste Examples)
Published Oct 15, 2026 · 9 min read
Short answer: a Claude Code skill is a folder containing a SKILL.md file. The file has YAML frontmatter (at minimum a name and a description) followed by Markdown instructions. Put it in .claude/skills/<name>/SKILL.md for a project or ~/.claude/skills/<name>/SKILL.md for every project. Claude loads the skill automatically when your request matches the description, or you run it yourself with /name.
Skills are the most underused part of Claude Code. Most people keep pasting the same checklist into chat ("run the tests, then lint, then write a commit message") or let their CLAUDE.md grow into a 400-line procedures manual. Both waste context. A skill fixes this: only its name and description sit in context until it's needed, and the full body loads only when the skill runs.
This guide covers where skills live, every frontmatter field that matters, how skills differ from subagents and slash commands, and five working skills you can paste into a repo today.
Where skill files live
| Location | Scope | Use it for |
|---|---|---|
.claude/skills/<name>/SKILL.md | This project, shared through git | Team workflows: ship a feature, release, review a diff |
~/.claude/skills/<name>/SKILL.md | You, in every repo | Personal habits: PR descriptions, standup notes |
A plugin's skills/ folder | Anyone who installs the plugin | Distributing skills across many repos |
The folder name (or the name field) becomes the command you type. A skill can carry supporting files next to SKILL.md. Common subfolders are scripts/ for executable helpers, references/ for long docs Claude should read only when needed, and assets/ for templates.
.claude/skills/
└── release/
├── SKILL.md
├── scripts/
│ └── bump-version.sh
└── references/
└── changelog-style.md
The SKILL.md format
Every skill has two parts: frontmatter between --- markers and Markdown instructions after it.
---
name: review-diff
description: Reviews the current git diff for bugs, missing tests and risky changes. Use when the user asks for a review, before committing, or before opening a PR.
---
1. Run `git diff --staged` (fall back to `git diff` if nothing is staged).
2. For each problem, report `file:line`, the issue, and a concrete fix.
3. Flag any change to auth, payments, migrations or env handling as HIGH RISK.
4. End with exactly one verdict line: APPROVE or REQUEST CHANGES.
The fields you'll actually use:
name: lowercase with hyphens. This is the/commandname.description: the most important line in the file. Claude matches requests against it to decide whether to load the skill, so say what it does and when to use it ("Use when...").disable-model-invocation: true: Claude never triggers the skill by itself; only you can, with/name. Use it for anything with side effects, such as deploys and releases.allowed-tools: pre-approves specific tools while the skill runs, for exampleBash(git diff:*), Read, Grep.argument-hint: shows the expected arguments in the autocomplete menu, for example[version].context: fork: runs the skill in its own subagent context, so a long investigation doesn't flood your main conversation.
Arguments typed after the command are available as $ARGUMENTS. You can also inject live shell output into the prompt before Claude sees it with the !`command` syntax, which grounds the skill in the actual state of your repo instead of guesses.
Skills vs subagents vs CLAUDE.md
| CLAUDE.md | Skill | Subagent | |
|---|---|---|---|
| Loaded | Every session, every turn | Only when invoked or matched | When delegated to |
| Best for | Facts: commands, conventions | Procedures and checklists | Isolated roles with their own tools |
| Context cost | Always paid | Near zero until used | Separate context window |
A good rule: if a section of CLAUDE.md starts with "When you do X, follow these steps", move it into a skill. If you want a role with a restricted toolset (say, a reviewer that can't edit files), make it a subagent instead. Skills and subagents work well together: a /ship-feature skill can hand the plan to a planner subagent and the review to a code-reviewer subagent.
5 skills worth copying
1. summarize-changes (auto-invoked, read-only)
---
name: summarize-changes
description: Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff.
allowed-tools: Bash(git status:*), Bash(git diff:*)
---
## Current state
!`git status --short`
## Diff
!`git diff HEAD`
Summarize the changes above in 3 to 6 bullets grouped by area.
Then list anything risky: deleted tests, new dependencies, edited env or config files.
Finish with a one-line conventional commit message.
Because the diff is injected with !`git diff HEAD`, Claude reasons about your real working tree, not whatever files happen to be open.
2. write-tests (argument-driven)
---
name: write-tests
description: Writes focused unit tests for a file or function. Use when the user asks for tests, coverage, or edge cases.
argument-hint: [path-or-function]
---
Target: $ARGUMENTS
1. Read the target and its existing tests. Match the test framework and style already used.
2. List the behaviours and edge cases (empty input, boundaries, errors) before writing code.
3. Write the tests. Do not change source code to make tests pass.
4. Run the single test file and report pass/fail with the command you used.
3. release (manual only, has side effects)
---
name: release
description: Cuts a release: bumps version, updates CHANGELOG, tags. Only run when explicitly asked.
disable-model-invocation: true
argument-hint: [major|minor|patch]
allowed-tools: Bash(npm test:*), Bash(git tag:*), Bash(./.claude/skills/release/scripts/bump-version.sh:*)
---
1. Refuse if the working tree is dirty. Show `git status`.
2. Run `npm test`. Stop on any failure.
3. Run `scripts/bump-version.sh $ARGUMENTS`.
4. Add a CHANGELOG entry following references/changelog-style.md.
5. Show the diff and the tag command. Wait for my "go" before tagging.
disable-model-invocation: true matters here: you never want Claude deciding on its own that now is a good time to tag a release.
4. explain-codebase (forked context)
---
name: explain-codebase
description: Produces an onboarding map of the repo or one area of it. Use when the user is new to the code or asks how something works end to end.
context: fork
allowed-tools: Read, Grep, Glob
---
Scope: ${ARGUMENTS:-the whole repo}
Produce:
- A 5-line summary of what the code does
- The entry points and the main request/data flow
- The 10 files a new contributor should read first, with one line each
- Any surprising conventions or footguns
Exploration reads a lot of files. Running it in a forked context keeps all of that out of your main session; you get only the summary back.
5. pr-description (personal skill)
---
name: pr-description
description: Writes a pull request description from the current branch. Use when creating a PR or summarizing branch changes.
---
Run `git log --oneline main..HEAD` and `git diff main...HEAD --stat`.
Write:
- **What**: one sentence
- **Why**: the problem it solves
- **Changes**: grouped bullets
- **Testing**: exact commands run and results
- **Risk**: what could break, and how to roll back
Save this one in ~/.claude/skills/ so it follows you to every repo.
Making skills trigger reliably
- Write descriptions like search queries. Include the words people actually type: "review", "tests", "PR", "what changed".
- One job per skill. A skill that "handles testing, linting and deployment" matches everything and nothing.
- Keep the body short and point to references. Put the 300-line style guide in
references/and tell Claude when to read it. - Use numbered steps with a clear stop condition. "Stop on any failure" and "wait for my go" prevent runaway runs.
- Back up must-never rules with hooks. A skill is instructions; a hook is enforcement. Pair a release skill with a hook that blocks
git push --force.
Common mistakes
- Vague descriptions. "Helps with code" never matches. "Reviews the current git diff... Use when..." does.
- Side-effect skills without
disable-model-invocation. Deploys, releases and migrations should be manual only. - Directory and name mismatch. Keep the folder name and the
namefield identical to avoid confusion. - Duplicating CLAUDE.md. Facts stay in CLAUDE.md; procedures move to skills. Don't keep both copies.
Get 4 tested skills plus the agents they call
The Claude Code Agent Starter Kit ($39) ships /ship-feature, /write-tests, /review-diff and /explain-codebase, wired to four subagents, three safety hooks and five CLAUDE.md templates. Get the Starter Kit: $39 Free safety hooks
FAQ
What is a Claude Code skill?
A skill is a folder containing a SKILL.md file: YAML frontmatter with a name and description, followed by Markdown instructions. Claude loads it automatically when a request matches the description, or you run it with /name. Only the name and description sit in context until the skill is used.
Where do I put SKILL.md?
Use .claude/skills/<name>/SKILL.md for a project skill shared through git, or ~/.claude/skills/<name>/SKILL.md for a personal skill available in every repo. Plugins can also ship skills.
How do I stop Claude from running a skill automatically?
Add disable-model-invocation: true to the frontmatter. The skill then only runs when you type its /name, which is what you want for deploys, releases and anything else with side effects.
What is the difference between a skill and a slash command?
They have been merged. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy. Skills add a folder for supporting files, automatic invocation and options such as running in a forked context.
Why isn't my skill triggering?
Usually the description is too vague. Say what the skill does and when to use it, using the words people actually type, such as review, tests, PR or what changed. Keep one job per skill.