Skills System
Skills are a system for defining instructions Claude Code should follow, or workflows it should run, in specific situations. You can invoke them directly as slash commands (/commit, /review), or let Claude load them automatically when the context calls for it.
The SKILL.md File Formatโ
Every skill uses a SKILL.md file as its entry point. It consists of YAML frontmatter plus a Markdown body:
---
name: explain-code
description: Explains code with visual diagrams and analogies. Used when someone asks "how does this code work?"
---
Always include the following when explaining code:
1. **Start with an analogy**: Compare the code to something from everyday life
2. **Draw a diagram**: Visualize flow, structure, and relationships in ASCII art
3. **Explain step by step**: Walk through how the code executes, in order
4. **Highlight gotchas**: Common mistakes and misconceptions
Two Content Typesโ
| Type | Purpose | How it runs |
|---|---|---|
| Reference content | Conventions, patterns, style guides, and so on | Applied inline alongside the conversation context |
| Task content | Step-by-step instructions for deploying, committing, generating code, etc. | Invoked directly with /skill-name, often with disable-model-invocation: true |
Keep SKILL.md under 500 lines. Split detailed reference material into separate supporting files.
YAML Frontmatter Fieldsโ
Every field is optional. Only description is recommended.
| Field | Description |
|---|---|
name | Display name. Lowercase letters, digits, and hyphens only (max 64 characters). Falls back to the directory name if omitted |
description | What the skill is for and when to use it. Claude uses this to decide whether to invoke it automatically |
argument-hint | Autocomplete hint. For example: [issue-number], [filename] [format] |
disable-model-invocation | If true, only the user can invoke it (blocks automatic invocation by Claude) |
user-invocable | If false, hidden from the / menu (only Claude can invoke it) |
allowed-tools | Tools usable without a permission prompt while the skill is active |
model | The model to use while the skill is active |
context | Set to fork to run in an isolated subagent |
agent | The agent type to use with context: fork (Explore, Plan, general-purpose, or a custom one) |
hooks | Hooks scoped to the skill's lifecycle |
Invocation Control and Token Optimizationโ
The key advantage of skills is on-demand loading. At the start of a session, Claude only includes each skill's description in context; the actual body is loaded only when the skill is invoked. Thanks to this structure, the context cost stays minimal even as your skill count grows.
| Frontmatter | User invocation | Claude invocation | Context loading |
|---|---|---|---|
| (default) | Yes | Yes | Description always loaded, full body on invocation |
disable-model-invocation: true | Yes | No | Description not loaded, full body only on invocation |
user-invocable: false | No | Yes | Description always loaded, full body on invocation |
If your skill descriptions exceed a certain share of the context window (2% by default), some skills may be excluded. Use /context to check whether any skills were left out. Setting disable-model-invocation: true on manual-only skills removes their descriptions from context entirely, freeing up room.
Skill Directory Structureโ
.claude/skills/
โโโ my-skill/
โโโ SKILL.md # Main instructions (required)
โโโ template.md # A template for Claude to fill in
โโโ examples/
โ โโโ sample.md # Example of the expected output
โโโ scripts/
โโโ validate.sh # A script for Claude to run
Scope by Locationโ
| Location | Scope | Priority |
|---|---|---|
| Managed settings | Entire organization | Highest |
~/.claude/skills/ | All projects (personal) | High |
.claude/skills/ | Current project | Medium |
Plugin skills/ | While the plugin is enabled | Low |
If a skill with the same name exists at multiple levels, the higher-priority one wins. Plugin skills use the plugin-name:skill-name namespace, so they never collide.
Files in .claude/commands/ still work and support the same frontmatter. When names match, .claude/skills/ takes precedence.
String Substitutionโ
You can use dynamic values inside a skill body:
| Variable | Description | Example |
|---|---|---|
$ARGUMENTS | All arguments passed in | /fix-issue 123 โ $ARGUMENTS = 123 |
$ARGUMENTS[N] | The Nth argument (0-based) | /migrate A B C โ $ARGUMENTS[1] = B |
$N | Shorthand for $ARGUMENTS[N] | $0, $1, $2 |
${CLAUDE_SESSION_ID} | The current session ID | Logging, creating per-session files |
${CLAUDE_SKILL_DIR} | Path to the directory containing SKILL.md | Useful for referencing bundled scripts and files |
---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
Fix GitHub issue $ARGUMENTS in line with our coding standards.
1. Read the issue description
2. Identify the requirements
3. Implement the fix
4. Write tests
5. Create a commit
When you run /fix-issue 123, $ARGUMENTS is substituted with 123.
If a skill contains no $ARGUMENTS, Claude Code automatically appends ARGUMENTS: <input> to the end of the body.
Dynamic Context Injection (!`command`)โ
The !`command` syntax runs a shell command before the skill is handed to Claude, and replaces the expression with the command's output:
---
name: pr-summary
description: Summarize PR changes
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---
## PR context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
## Task
Summarize this PR...
Claude receives the actual execution results, not the commands themselves.
Subagent Execution (context: fork)โ
Setting context: fork runs the skill in an isolated subagent:
---
name: deep-research
description: Research a topic in depth
context: fork
agent: Explore
---
Research $ARGUMENTS in depth:
1. Find the relevant files with Glob and Grep
2. Read and analyze the code
3. Summarize with specific file references
The subagent has no access to the conversation history and returns only its results to the main conversation. The agent field determines the execution environment (model, tools, permissions).
Bundled Skillsโ
Claude Code ships with built-in skills available in every session:
| Skill | Description |
|---|---|
/simplify | Reviews and fixes code quality, reusability, and efficiency in recently changed files |
/batch <instruction> | Breaks a large change into parallel agents (uses git worktrees) |
/debug [description] | Reads the current session's debug logs and diagnoses problems |
/loop [interval] <prompt> | Runs a prompt repeatedly on an interval (e.g. /loop 5m check whether the deploy finished) |
/claude-api | Loads the Claude API reference for your project's language |
Automatic Nested Directory Discoveryโ
When you are working in a subdirectory, Claude Code also discovers the .claude/skills/ directory along that path automatically. For example, if you are editing inside packages/frontend/, skills in packages/frontend/.claude/skills/ are recognized too. This is useful for running per-package skills in a monorepo.
When names collide (v2.1.178+), the nested skill is displayed as <directory>:<name>, so both stay available. In addition, when agents, workflows, and output styles share a name, the .claude/ directory closest to the working directory wins (closest-wins).
The Agent Skills Open Standardโ
Claude Code skills follow the Agent Skills open standard, which works across multiple AI tools. Claude Code additionally supports invocation control, subagent execution, and dynamic context injection.
Practical Examplesโ
Code Review Skillโ
---
name: review
description: Perform a code review
allowed-tools: Read, Grep, Glob
---
Perform a code review:
1. Identify the changed files
2. Check for security vulnerabilities
3. Check for performance problems
4. Check code style consistency
5. Give specific improvement suggestions
Commit Skillโ
---
name: commit
description: Create a commit from the staged changes
disable-model-invocation: true
allowed-tools: Bash(git *)
---
Analyze the staged changes and write an appropriate commit message:
1. Check `git diff --staged`
2. Use the Conventional Commits format
3. Focus on the "why" behind the change
Deploy Skill (Dynamic Context)โ
---
name: deploy
description: Run a production deployment
disable-model-invocation: true
context: fork
---
## Current state
- Current branch: !`git branch --show-current`
- Recent commits: !`git log --oneline -5`
- Test status: !`npm test 2>&1 | tail -3`
## Deployment procedure
Deploy to the $ARGUMENTS environment...
Managing Skillsโ
Creating and Invokingโ
/skill-name # Direct invocation
/skill-name value # Invocation with an argument
/skill-name arg1 arg2 # Multiple arguments
Skill Stackingโ
You can invoke several skills at once by stacking them side by side at the front:
/skill-a /skill-b clean up this PR
As of v2.1.199, up to 5 skills stacked consecutively at the front are all loaded (previously, only the first skill was loaded). For example, you can stack a coding convention skill and a commit message skill and have both applied in a single request.
Only skills stacked consecutively at the very beginning of the prompt are loaded, up to a maximum of 5. Write your actual request after them.
Controlling with Permissionsโ
{
"permissions": {
"allow": ["Skill(commit)"], // Allow only specific skills
"deny": ["Skill(deploy *)"] // Block specific skills
}
}
Distribution Scopeโ
- Project: Commit
.claude/skills/to git - Plugin: Package it in the plugin's
skills/directory - Managed: Distribute organization-wide via managed settings