Agent Shipped

Guide · updated 2026-10-12 · 8 min read

Claude Code Skills: How to Build and Use Them

Claude Code skills are reusable instructions packaged as a folder with a SKILL.md file: YAML frontmatter that says what the skill does and when to use it, followed by Markdown instructions. Put one in .claude/skills/<name>/SKILL.md (project) or ~/.claude/skills/<name>/SKILL.md (personal), and Claude loads it when your request matches its description, or you run it yourself with /name.

The skills docs give the clearest rule for when to write one: when you keep pasting the same instructions, checklist or procedure into chat, or when a section of CLAUDE.md "has grown into a procedure rather than a fact." Unlike CLAUDE.md, a skill's body only loads when it's used.

Skills, commands, CLAUDE.md and subagents

Some quick orientation, because these overlap:

Skills also follow the Agent Skills open standard, which is why the same folder can work in other tools. Cursor's docs, for example, say it reads .claude/skills/ too.

Build your first skill

This is the docs' starter example, and it's a genuinely useful one. It summarizes your uncommitted changes and flags risks.

mkdir -p ~/.claude/skills/summarize-changes

Save this as ~/.claude/skills/summarize-changes/SKILL.md:

---
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.

Now ask "what did I change?" and Claude picks it up, or type /summarize-changes. The !`git diff HEAD` line is dynamic context injection: Claude Code runs the command and swaps in its output before Claude sees the skill, so Claude works from your real diff.

Claude Code watches skill directories, so edits apply in the current session without a restart. If you created a brand-new top-level skills directory mid-session, run /reload-skills.

Where skills live

Location Path Loads in
Personal ~/.claude/skills/<name>/SKILL.md All your projects on this machine
Project .claude/skills/<name>/SKILL.md This repo. Commit it for your team.
Nested <subdir>/.claude/skills/<name>/SKILL.md Sessions in or below that folder, or once Claude works on files there
Plugin <plugin>/skills/<name>/SKILL.md Wherever the plugin is enabled, as /plugin-name:skill-name
Enterprise Managed settings directory Everyone your org deploys it to

One gotcha that bites people: cloud sessions, routines and Cowork don't read ~/.claude/skills/ from your machine. For those, either commit the skill to the repo's .claude/skills/ or enable it on your claude.ai account.

When names collide, enterprise beats personal and personal beats project. A project skill with the same name as a bundled skill replaces it.

The frontmatter fields that matter

Every field is optional. description is the one you should always write, because it's how Claude decides when to use the skill. The frontmatter reference has the full list; these are the ones worth knowing:

Field What it does
name Command name. Defaults to the folder name.
description What it does and when to use it. Put the key use case first.
when_to_use Extra trigger phrases, appended to the description.
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 the turn that invokes the skill.
argument-hint Autocomplete hint, such as [issue-number].
context fork runs the skill in a subagent.
agent Which subagent type to use with context: fork.
model / effort Override model or effort while the skill is active.
paths Globs that limit when Claude auto-loads the skill.
hooks Hooks registered when the skill is invoked.

Field names use hyphens (except when_to_use) and must match exactly. Claude Code ignores a field it doesn't recognize, without an error. The combined description and when_to_use text is truncated at 1,536 characters in the skill listing.

Control who runs it

This is the single most important decision for each skill.

---
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

With disable-model-invocation: true, Claude can't decide to deploy because your code "looks ready." You type /deploy staging. The description also stays out of context until you invoke it.

The opposite, user-invocable: false, suits background knowledge such as a legacy-system-context skill that Claude should consult when relevant but that isn't a meaningful command for you to type.

A small detail from the docs: /deploy staging at the start of a message runs the skill. Typing "go ahead and /deploy to staging" mid-sentence only gives Claude permission to run it.

Arguments

Skills take arguments through substitutions:

The docs' issue-fixing skill from the best practices page is a good template:

---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
Analyze and fix the GitHub issue: $ARGUMENTS.

1. Use `gh issue view` to get the issue details
2. Understand the problem described in the issue
3. Search the codebase for relevant files
4. Implement the necessary changes to fix the issue
5. Write and run tests to verify the fix
6. Ensure code passes linting and type checking
7. Create a descriptive commit message
8. Push and create a PR

Run it with /fix-issue 1234.

Bundle scripts without permission prompts

Combine ${CLAUDE_SKILL_DIR} with allowed-tools and a skill can run its own script without prompting you:

---
name: render-chart
description: Render a chart from a CSV file
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---

Run `${CLAUDE_SKILL_DIR}/scripts/render.sh <csv-file>` to render the chart.

The allowed-tools grant only lasts for the turn that invoked the skill. It doesn't restrict other tools, and it doesn't carry into your next message. For session-wide approvals, use permission rules in settings.

Supporting files work the same way. Keep SKILL.md under 500 lines, put long reference material in reference.md or examples.md next to it, and link them from SKILL.md so Claude knows when to open them.

Run a skill in a subagent

Add context: fork and the skill runs in an isolated subagent, which doesn't see your conversation history:

---
name: deep-research
description: Research a topic thoroughly
context: fork
agent: Explore
---

Research $ARGUMENTS thoroughly:

1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Summarize findings with specific file references

Forked skills run in the background by default. Set background: false to wait for the result in the same turn. Two cautions from the docs: context: fork only makes sense for skills with an actual task, not guidelines, and edits made by a backgrounded fork aren't covered by /rewind, so use git to revert them.

Bundled skills you already have

Claude Code ships with bundled skills including /code-review, /debug, /loop, /batch, /claude-api and /doctor. A few worth knowing:

When skills don't behave

Not triggering. Make sure the description uses words you'd actually say. Ask "What skills are available?" to check it loaded. If the YAML is malformed the body still loads but with empty metadata, so /name works and auto-matching doesn't. Run claude plugin validate .claude/skills to find bad frontmatter.

Triggering too often. Make the description more specific, or add disable-model-invocation: true.

Followed at first, then ignored. Claude Code doesn't re-read the skill file on later turns, so word rules as standing instructions ("run the tests after every edit"). After compaction, only the first 5,000 tokens of each recent skill are re-attached, so put the important parts at the top. Rules that must hold every time belong in a hook, which you can define in the skill's own hooks frontmatter.

Descriptions cut short. With many skills, Claude Code drops descriptions of your least-used ones to fit a budget of 1% of the context window. Raise it with skillListingBudgetFraction, or prune.

Bottom line

Write your first skill for the procedure you explain most often: a release checklist, a PR summary, a migration recipe. Give it a specific description, set disable-model-invocation: true on anything with side effects, keep SKILL.md short with reference files beside it, and commit project skills so your team gets them. When a CLAUDE.md section starts reading like a how-to, it's a skill. More on how skills fit into a full setup in Claude Code best practices.

Subscribe to Agent Shipped for a copy-paste skill, hook or subagent in every issue, twice a week.

FAQ

What is a skill in Claude Code?

A skill is a folder with a SKILL.md file containing YAML frontmatter and Markdown instructions. Claude loads it automatically when your request matches its description, or you run it directly by typing /skill-name.

What is the difference between skills and slash commands?

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. Skills add a folder for supporting files and frontmatter to control who can invoke them.

How do I stop Claude from running a skill on its own?

Add disable-model-invocation true to the frontmatter. Claude can then only run it when you type /skill-name, which is what you want for deploys, commits and anything with side effects.

Do skills cost context when they are not used?

Only a little. Skill names and descriptions are listed in context so Claude knows what exists, but the full body loads only when the skill is invoked. Skills with disable-model-invocation true keep even the description out of context.

Get the field guide

Join builders who use coding agents every day. Free, twice a week, unsubscribe in one click.

No spam. You get the CLAUDE.md starter pack in your welcome email.

Keep reading