Guides
Claude Code skills: how to use them and write SKILL.md
A skill is a SKILL.md file of instructions: Claude uses it when it is relevant, or you can invoke it directly with /skill-name. This page walks through Anthropic's Extend Claude with skills documentation: creating a first skill, where skills live, how to write the frontmatter, how to control who invokes a skill, and what to check when one does not trigger. The documentation was checked on October 30, 2026.
- Create a
SKILL.mdfile and Claude adds it to its toolkit. Claude uses it when relevant, or you invoke it directly with/skill-name. - A personal skill goes in
~/.claude/skills/<skill-name>/SKILL.mdand a project skill in.claude/skills/<skill-name>/SKILL.md. On a name clash, enterprise wins over personal, and personal over project. - Every field is optional. Only
descriptionis recommended, because Claude uses it to decide when to apply the skill. - To stop Claude from using a skill on its own, set
disable-model-invocation: truein its frontmatter. - Custom commands have been merged into skills:
.claude/commands/deploy.mdand.claude/skills/deploy/SKILL.mdboth create/deployand work the same way.
When to write a skill
The documentation's test: you keep pasting the same instructions, checklist, or multi-step procedure into chat, or a section of CLAUDE.md has grown into a procedure rather than a fact. Unlike CLAUDE.md content, a skill's body loads only when it is used, so long reference material costs almost nothing until you need it. For CLAUDE.md itself, see how to write CLAUDE.md.
The documentation also says custom commands have been merged into skills. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and work the same way, and existing .claude/commands/ files keep working. What skills add is a directory for supporting files, frontmatter to control whether you or Claude invokes them, and the ability for Claude to load them automatically when relevant.
Create your first skill
This example comes from the documentation: a skill that summarizes the uncommitted changes in a git repository and flags anything risky. First, create a directory for it in your personal skills folder. Personal skills are available across all your projects:
mkdir -p ~/.claude/skills/summarize-changes
Second, write SKILL.md. Every skill needs this file, in two parts: YAML frontmatter between --- markers that tells Claude when to use the skill, and markdown content with the instructions Claude follows when the skill runs.
---
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.
---
## Current changes
!`git diff HEAD`
## Instructions
Summarize the changes above in two or three bullet points, then list any risks you notice such as missing error handling, hardcoded values, or tests that need updating. If the diff is empty, say there are no uncommitted changes.
The directory name, or the frontmatter name when you set one, becomes the command you type, and the description helps Claude decide when to load the skill automatically. The !`git diff HEAD` line uses dynamic context injection: Claude Code runs the command and replaces the line with its output before Claude sees the skill content, so the instructions arrive with the current diff already inlined.
Third, test it. Open a git project, make a small edit to any file, and start Claude Code by running claude. Either way works:
What did I change? # matches the description, so Claude can invoke it automatically
/summarize-changes # or invoke it directly with the skill name
Either way, Claude should respond with a short summary of your edit and a list of risks.
Where skills live
Where you save a skill decides which sessions load it. Save it under your home directory to get it in every project, commit it to a repository to share it with everyone who works there, or distribute it through a plugin or managed settings to reach a whole team.
| Location | Path | Loads in |
|---|---|---|
| Enterprise | .claude/skills/<skill-name>/SKILL.md in the managed settings directory | All users on machines where your organization deploys it |
| Personal | ~/.claude/skills/<skill-name>/SKILL.md | All your projects on this machine, but not Cowork or cloud sessions |
| Project | .claude/skills/<skill-name>/SKILL.md | Sessions in this repository. Commit it so your team gets it too |
| Nested | <subdir>/.claude/skills/<skill-name>/SKILL.md | Sessions started in or below <subdir>; a session started above it loads the skill once Claude works on files there |
| Additional directory | .claude/skills/<skill-name>/SKILL.md in a directory you pass with --add-dir | That session |
| Plugin | <plugin>/skills/<skill-name>/SKILL.md | Wherever the plugin is enabled, as /plugin-name:skill-name |
When two skills share a name (an excerpt of the documentation's table):
- Same name in two of enterprise, personal, and project: enterprise over personal, and personal over project. With
deployin both~/.claude/skills/and the project's.claude/skills/,/deployruns the personal one. - A skill and a file in
.claude/commands/: the skill. - A plugin skill and a skill at any of the locations above: both load, because plugin skills are namespaced as
/plugin-name:skill-name.
One more rule: skills in a .claude/skills/ directory below where you started do not load at startup. They load the first time Claude reads or edits a file in that subdirectory. Until then they do not appear in the / menu and you cannot invoke them by name.
You do not need to restart after changing a skill. Claude Code watches skill directories, so adding, editing or removing a skill under ~/.claude/skills/ or the project .claude/skills/ takes effect within the current session. If you create a top-level skills directory that did not exist when the session started, run /reload-skills.
The frontmatter fields that matter most
All fields are optional. Only description is recommended. A field name must match the table exactly, hyphens included: Claude Code ignores a field it does not recognize without reporting an error. Boolean fields accept yes, no, on, off, 1, and 0 in any letter case, in addition to true and false.
| Field | Required | What it does |
|---|---|---|
name | No | Command name shown in the / menu. Defaults to the directory name. |
description | Recommended | What the skill does and when to use it. Claude uses this to decide when to apply the skill. If omitted, uses the first non-empty line of the markdown content. |
when_to_use | No | Additional context for when Claude should invoke the skill, such as trigger phrases or example requests. Appended to description and counted toward the 1,536-character cap. |
argument-hint | No | Hint shown during autocomplete to indicate expected arguments, such as [issue-number] or [filename] [format]. |
arguments | No | Named positional arguments for $name substitution in the skill content. Accepts a space-separated string or a YAML list. |
disable-model-invocation | No | Set to true to prevent Claude from automatically loading this skill. Use for workflows you want to trigger manually with /name. Default: false. |
user-invocable | No | Set to false when only Claude should invoke the skill: Claude Code hides it from the / menu and does not run it when you type /name. Default: true. |
allowed-tools | No | Tools Claude can use without asking permission during the turn that invokes this skill. The grant clears when you send your next message. |
paths | No | Glob patterns that limit when this skill is activated. When set, Claude loads the skill automatically only when working with files matching the patterns. |
context | No | Set to fork to run in a forked subagent context. |
The documentation lists more fields, including model, effort, agent, background, hooks, shell, metadata, license and compatibility; they are not covered here. One caveat: Claude Code reads the frontmatter only when the opening --- is the file's first line. Otherwise it treats the whole file, --- markers included, as skill content.
Invoking a skill yourself or letting Claude choose
By default, both you and Claude can invoke any skill. You type /skill-name to invoke it directly, and Claude can load it automatically when relevant to your conversation. Two frontmatter fields restrict this:
disable-model-invocation: true: Claude cannot invoke the skill on its own. Use this for workflows with side effects or that you want to control the timing of, like/commit,/deploy, or/send-slack-message. You do not want Claude deciding to deploy because your code looks ready.user-invocable: false: only Claude can invoke the skill. Use this for background knowledge that is not actionable as a command, such as alegacy-system-contextskill that explains how an old system works.
| Frontmatter | You can invoke | Claude can invoke | When loaded into context |
|---|---|---|---|
| (default) | Yes | Yes | Description always in context, full skill loads when invoked |
disable-model-invocation: true | Yes | Not on its own | Description not in context, full skill loads when invoked |
user-invocable: false | No | Yes | Description always in context, full skill loads when invoked |
The documentation's deploy example:
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
---
Deploy $ARGUMENTS to production:
1. Run the test suite
2. Build the application
3. Push to the deployment target
4. Verify the deployment succeeded
If Claude tries anyway, Claude Code blocks the call and instructs it not to reproduce the deploy steps another way, so expect Claude to suggest running /deploy yourself.
To run a skill directly, put its name at the start of your message: /deploy staging runs the skill directly. After plain text, as in go ahead and /deploy to staging, nothing runs directly. The name counts as your permission for that message: Claude can run the skill while it responds, and judges from your wording whether you asked it to. To write about the skill without permitting a run, leave off the slash.
Arguments and supporting files
Both you and Claude can pass arguments when invoking a skill. Arguments are available through the $ARGUMENTS placeholder, which is replaced with whatever follows the skill name:
---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Understand the requirements
3. Implement the fix
4. Write tests
5. Create a commit
When you run /fix-issue 123, Claude receives "Fix GitHub issue 123 following our coding standards...". To access individual arguments by position, use $ARGUMENTS[N] or the shorter $N. If you invoke a skill with arguments but no placeholder in the skill's content receives one, Claude Code appends ARGUMENTS: <your input> to the end of the skill content so Claude still sees what you typed.
A skill directory can hold several files. That keeps SKILL.md focused on the essentials while Claude reads detailed reference material only when needed:
my-skill/
├── SKILL.md (required - overview and navigation)
├── reference.md (detailed API docs - loaded when needed)
├── examples.md (usage examples - loaded when needed)
└── scripts/
└── helper.py (utility script - executed, not loaded)
Reference the supporting files from SKILL.md so Claude knows what each file contains and when to load it:
## Additional resources
- For complete API details, see [reference.md](reference.md)
- For usage examples, see [examples.md](examples.md)
The documentation's tip: keep SKILL.md under 500 lines and move detailed reference material to separate files.
Writing a good description
- Use keywords users would naturally say. The first item in the documentation's troubleshooting list is to check that the description includes them. The example above states the trigger directly: "Use when the user asks what changed, wants a commit message, or asks to review their diff."
- Put the key use case first. The combined
descriptionandwhen_to_usetext is truncated at 1,536 characters in the skill listing. - Make it more specific if it fires too often. That is the documentation's first suggestion when a skill triggers when you do not want it to.
- Angle brackets are escaped.
<and>indescriptionandwhen_to_usedisplay as<and>. To show a placeholder such as<branch>, use square brackets,[branch], or move it to a separateargument-hintline. - Keep the body short. Once a skill loads, its content stays in context across turns, so every line is a recurring token cost. State what to do rather than narrating how or why.
Troubleshooting
The skill does not trigger
- Check the description includes keywords users would naturally say.
- Verify the skill appears in the answer to
What skills are available? - Try rephrasing your request to match the description more closely.
- Invoke it directly with
/skill-nameif the skill is user-invocable. - If
/skill-nameis not recognized either, check whether Claude Code refused the skill's name (characters such as a zero-width space, a control character,<or>cause that). - If the skill sets
paths, check that the files Claude reads, edits, or writes are inside Claude's current working directory. The skill does not activate for files outside it, such as those in a sibling git worktree, even one you added with/add-dir.
If the frontmatter YAML is malformed, Claude Code loads the skill body with empty metadata, so /skill-name still works but Claude cannot match against your description. Run with --debug to see the parse error. To find SKILL.md files whose frontmatter does not parse, run claude plugin validate on the skills directory, for example claude plugin validate .claude/skills or claude plugin validate ~/.claude/skills. It requires Claude Code v2.1.233 or later.
The skill triggers too often
Make the description more specific. Add disable-model-invocation: true if you only want manual invocation.
Claude stops following a skill
When a skill is invoked, Claude Code adds its content to the conversation and does not re-read the file on later turns, so word guidance that applies to the whole task as "Run the tests after every edit" rather than "Run the tests". After compaction, Claude Code can keep only the start of an invoked skill, so put the most important instructions near the top of SKILL.md, and invoke the skill again to restore its full content. For a rule that must hold every time, the documentation recommends a hook instead.
Descriptions are cut short
With many skills, Claude Code drops some descriptions to fit the listing's character budget, which removes the keywords Claude needs to match your request. The budget scales at 1% of the model's context window, and descriptions are dropped starting with the skills you invoke least. Run /doctor for an estimate of the listing's context cost and its biggest contributors.
FAQ
Do my old .claude/commands/ files still work?
Yes. The documentation says custom commands have been merged into skills and existing .claude/commands/ files keep working. They support the same frontmatter except name and paths. Prefer a skill for new work, since skills also support supporting files. When a skill and a .claude/commands/ file share a name, the skill wins.
How do I stop Claude from using a skill automatically?
Add disable-model-invocation: true to its frontmatter. Claude can then no longer invoke it on its own, and it runs when you type /name. If you do not want to edit the file, the documentation says you can set the skill to "user-invocable-only" in skillOverrides.
What belongs in CLAUDE.md and what belongs in a skill?
Per the documentation, a section of CLAUDE.md that has grown into a procedure is a candidate for a skill, because, unlike CLAUDE.md content, a skill's body loads only when it is used. For writing CLAUDE.md, see how to write CLAUDE.md; for installing and connecting Claude Code, see Claude Code setup.
Sources
- Claude Code: Extend Claude with skills (skill locations, name clashes, frontmatter fields, invocation control, arguments, supporting files, troubleshooting)