Your first skill in 10 minutes
Write a SKILL.md with frontmatter, run it with a slash command or let Claude load it, and split long material into supporting files.
A skill is a folder with a SKILL.md file that teaches Claude a procedure. You run it with a slash command, or Claude loads it on its own when your request matches. This guide is for anyone who keeps pasting the same checklist into chat. At the end you will have a working skill, know how its frontmatter controls who can run it, and know how to keep it light on context.
What you will have at the end
- A personal skill that summarizes your uncommitted changes and flags risks
- A clear sense of what goes in frontmatter and what goes in the body
- A manual-only skill for actions with side effects
- A skill folder with supporting files that load only when needed
Before you start
- Claude Code installed and signed in. See Start here.
- A git project with at least one uncommitted edit, so the example has something to read.
- A shell where
mkdirworks. On Windows, use WSL or Git Bash for the commands below.
Step 1: Create the skill folder
Personal skills live under your home directory and work in all your projects:
mkdir -p ~/.claude/skills/summarize-changesThe skills docs list the main locations:
| Where | Path | Loads in |
|---|---|---|
| Personal | ~/.claude/skills/<skill-name>/SKILL.md |
All your projects on this machine |
| Project | .claude/skills/<skill-name>/SKILL.md |
This repository. Commit it so your team gets it |
| Plugin | <plugin>/skills/<skill-name>/SKILL.md |
Wherever the plugin is enabled |
The folder name becomes the command you type, unless you set a name in frontmatter.
Step 2: Write SKILL.md
Save this as ~/.claude/skills/summarize-changes/SKILL.md. It is the example from the skills docs:
---
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.A skill has two parts. The YAML frontmatter between the --- lines tells Claude when to use it. The markdown after it is what Claude follows when the skill runs.
The !`git diff HEAD` line is dynamic context injection. Claude Code runs the command first and puts its output in place of the line, so Claude sees your real diff instead of guessing (skills docs).
You do not need to restart. Claude Code watches the skill folders and picks up new or edited skills within the current session. The exception is a top-level skills folder that did not exist when the session started. Run /reload-skills once in that case (edit during a session).
Step 3: Run it two ways
Start claude in a project with an uncommitted edit. Then invoke the skill directly:
/summarize-changesOr ask in plain words and let Claude match it to the description:
What did I change?Either way you should get a short summary and a list of risks. If the plain question does not trigger the skill, your description needs the words people actually say. That is why the example names its triggers: "what changed", "commit message", "review their diff".
Step 4: Get the frontmatter right
All frontmatter fields are optional, but description is the one the docs recommend, because it is how Claude decides when to load the skill (frontmatter reference). Put the key use case first. The combined description and when_to_use text is cut at 1,536 characters in the skill listing.
The fields you will use most:
| Field | What it does |
|---|---|
name |
Command name in the / menu. Defaults to the folder name |
description |
What the skill does and when to use it |
argument-hint |
Hint shown in autocomplete, such as [issue-number] |
disable-model-invocation |
true means only you can run it, with /name |
user-invocable |
false hides it from the / menu so only Claude uses it |
allowed-tools |
Tools Claude can use without asking during that turn |
Field names must match exactly. Claude Code silently ignores a field it does not recognize, so a typo fails quietly.
Step 5: Make side-effect skills manual
Anything that deploys, sends a message or commits should run only when you say so. Add disable-model-invocation: true:
---
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 succeededThis example is from the skills docs. Claude now cannot start it on its own, and its description is no longer in Claude's context. $ARGUMENTS is replaced with whatever you type after the command, so /deploy staging deploys staging (string substitutions).
Step 6: Use progressive disclosure
In a normal session, Claude sees only skill names and descriptions. The full body loads when the skill is invoked (control who invokes). Once loaded, the body stays in the conversation across turns, so every line is a recurring cost.
Keep SKILL.md short and move long material into files next to it:
my-skill/
├── SKILL.md
├── reference.md
├── examples.md
└── scripts/
└── helper.pyThen point to them from SKILL.md so Claude knows what each file holds and when to open it, for example For complete API details, see [reference.md](reference.md). The docs suggest keeping SKILL.md under 500 lines (supporting files).
A good rule from the best practices page: write down only what Claude cannot find on its own. A skill is the right home for your release steps or runbook. It is the wrong home for general engineering advice the model already knows.
Check it worked
- Run
/skillsto list available skills. Yours should appear (commands). - Ask
What skills are available?and confirm Claude names it. /summarize-changesin a repo with an edit returns bullets and a risk list. In a clean repo it says there are no uncommitted changes.
Common problems
The skill never triggers on its own. Add the words people naturally say to the description, rephrase your request closer to it, or invoke it with /skill-name (troubleshooting).
The slash command works but Claude ignores the description. The frontmatter YAML is probably malformed, so the body loads with empty metadata. Run claude plugin validate ~/.claude/skills to find the parse error. It needs v2.1.233 or later.
The skill triggers too often. Make the description more specific, or add disable-model-invocation: true (troubleshooting).
Claude follows the skill at first, then drifts. Claude Code does not re-read the file on later turns. Word guidance so it covers the whole task, put the key rules near the top, and invoke the skill again after compaction (troubleshooting).
Next
- Subagents: when to split the work: run a skill in its own context with
context: fork. - Build a team skill library that stays sharp: the paid guide with skill templates and an eval checklist.
Sources
- https://code.claude.com/docs/en/skills
- https://code.claude.com/docs/en/best-practices
- https://code.claude.com/docs/en/commands
Last checked: 2026-11-06