Claude Code Skills: The Complete Guide
Everything you need to master Claude Code Skills — from basic concepts to advanced patterns. Learn what skills are, how they differ from CLAUDE.md, every frontmatter field, all invocation modes, and build your own with real-world examples.
What Are Skills?
Skills are reusable instruction sets packaged as Markdown files that extend Claude Code’s capabilities. Based on the open Agent Skills standard, they work across multiple AI tools — not just Claude Code.
Think of them as playbooks. You write a set of instructions once — how to deploy, how to review code, how to create a blog post — and then invoke it whenever you need it. Claude reads the playbook and executes it using all the tools at its disposal.
A skill is:
- A
.mdfile with YAML frontmatter (configuration) and Markdown body (instructions) - A self-contained unit that Claude can load automatically when relevant, or you invoke manually with
/skill-name - Available at multiple scopes: personal, project, enterprise, or packaged in plugins
- Discoverable by Claude through descriptions you provide
- Optionally executable in isolation via a subagent context
The key distinction: skills are prompt-based guidance. Claude reads them and follows them, but they’re instructions — not hard-enforcement rules like hooks or permissions. That’s a feature, not a bug. It means skills are flexible, composable, and easy to write.
Skills vs CLAUDE.md
This is the first question everyone asks: "If I can put instructions in CLAUDE.md, why do I need skills?" The answer is scope and loading.
The mental model is simple:
- CLAUDE.md = who you are and how you work (permanent context)
- Skills = what you do and when (on-demand playbooks)
Put your coding standards, build commands, and project architecture in CLAUDE.md. Put your deployment workflow, code review checklist, and PR template in skills. They complement each other — CLAUDE.md provides the rules, skills provide the actions.
Skill Types
Skills are classified along three dimensions: who can invoke them, where they run, and what they contain.
By Invocation Pattern
User-invocable (default) — You type /skill-name to run them. Claude can also invoke them automatically if the description matches your request.
Model-invocation disabled (disable-model-invocation: true) — Only you can invoke via /skill-name. Claude cannot trigger them automatically. Use this for workflows with side effects: deploying, committing, sending messages.
Hidden skills (user-invocable: false) — Only Claude can invoke them automatically. They don’t appear in the / menu. Use for background knowledge: legacy system docs, architectural context, domain conventions.
By Execution Context
Inline (default) — Runs in your main conversation. Claude can reference your conversation history. Results stay in the thread.
Forked (context: fork) — Runs in an isolated subagent. No access to conversation history. Results are summarized and returned. Perfect for high-volume operations like running test suites, processing large codebases, or deep research where you don’t want verbose output cluttering your context.
By Content Type
Reference skills contain knowledge or guidelines (API conventions, design patterns, style guides). They add context Claude applies to current work.
Task skills contain step-by-step instructions for specific actions (deploy, fix a bug, create a PR). They’re typically marked disable-model-invocation: true since you want to control when they run.
Where Skills Live
Skills are discovered from multiple filesystem locations. Higher priority locations override lower ones when names conflict.
Discovery Locations (Priority Order)
# 1. Enterprise (managed policy) — highest priority
# macOS: /Library/Application Support/ClaudeCode/.claude/skills/
# Linux: /etc/claude-code/.claude/skills/
# Windows: C:\Program Files\ClaudeCode\.claude\skills\
# 2. Project-level (your repo)
.claude/skills/<skill-name>/SKILL.md
# 3. Nested directories (monorepo auto-discovery)
packages/frontend/.claude/skills/<skill-name>/SKILL.md
packages/backend/.claude/skills/<skill-name>/SKILL.md
# 4. Personal / User-level (all your projects)
~/.claude/skills/<skill-name>/SKILL.md
# 5. Plugin-provided (namespaced)
~/.claude/plugins/<plugin-name>/skills/<skill-name>/SKILL.md
# → invoked as /plugin-name:skill-nameProject scope (.claude/skills/) is for team-shared workflows checked into version control. User scope (~/.claude/skills/) is for personal workflows across all your projects. Enterprise scope is deployed via MDM or Ansible and applies to all users on the machine.
Directory Structure
Each skill is a directory with a required SKILL.md and optional supporting files:
my-skill/
├── SKILL.md # Required: frontmatter + instructions
├── reference.md # Optional: detailed docs
├── examples.md # Optional: usage examples
├── templates/ # Optional: templates
│ └── api-response.md
└── scripts/ # Optional: executable scripts
├── validate.sh
└── helper.pyOnly SKILL.md is required. Supporting files are loaded by Claude on-demand when referenced from the main file. This keeps your skill lightweight — the full reference material only enters context when Claude actually needs it.
Legacy Compatibility
The older .claude/commands/ directory still works and supports the same frontmatter. If both exist with the same name, .claude/skills/ takes precedence. New skills should always use the skills/ directory.
The Skill File Format
This is the core of the system. A SKILL.md file has two parts: YAML frontmatter (configuration) and Markdown body (instructions).
Complete Frontmatter Reference
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
user-invocable: true
argument-hint: [environment]
allowed-tools: Bash, Read, Write
model: opus
effort: high
context: fork
agent: general-purpose
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./validate.sh"
---
Markdown body goes here — the actual instructions Claude follows.Here is every available frontmatter field:
String Substitutions
Skills support dynamic value substitution in both frontmatter and body:
Important: If $ARGUMENTS doesn’t appear anywhere in the skill content, Claude Code auto-appends ARGUMENTS: <value> to the end.
Shell Preprocessing
Skills can run shell commands and inject their output before Claude sees the prompt. Use the !`command` syntax:
---
name: pr-summary
---
## Pull Request Context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
## Your Task
Summarize this pull request...Each !`command` executes immediately when the skill loads. The output replaces the placeholder. Claude receives the fully-rendered prompt with actual data — not the commands themselves. This is how you inject live context into skills.
The Body: Instructions
The Markdown body after the frontmatter is the instruction prompt Claude follows. It can contain:
- Plain text instructions and step-by-step workflows
- Markdown formatting (headings, lists, code blocks, bold, links)
- References to supporting files:
See [reference.md](reference.md) for details - Shell preprocessing commands (
!`command`) - Variable substitutions (
$ARGUMENTS,${CLAUDE_SKILL_DIR})
Keep SKILL.md under 500 lines. Move detailed reference material to separate files in the same directory.
Invoking Skills
There are three ways to invoke a skill.
1. Slash Commands (Manual)
Type / followed by the skill name. Arguments go after:
/deploy production
/fix-issue 123
/explain-code src/auth/login.ts
/migrate-component SearchBar React VueType / alone to see a list of all available skills with autocomplete.
2. Auto-Invocation (Claude-Triggered)
Claude automatically loads a skill when:
- Your prompt matches the skill’s
description - The skill doesn’t have
disable-model-invocation: true - The skill’s
user-invocableis notfalse
For example, if a skill’s description says "Explains code with visual diagrams", and you ask "How does this function work?", Claude will automatically load and follow that skill’s instructions.
3. @-Mention (Explicit Delegation)
Type @ and select a skill from the menu:
@code-reviewer look at my auth changes
@"deep-research (skill)" investigate the database schemaThis forces a specific skill instead of letting Claude choose.
Invocation Control Matrix
Arguments and Parameters
Basic: Single Argument
---
name: fix-issue
argument-hint: [issue-number]
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Find and fix the bug
3. Write tests
4. Create a commit: "Fix #$ARGUMENTS"
Running /fix-issue 123 replaces every $ARGUMENTS with 123.
Multiple Arguments (Positional)
---
name: migrate-component
argument-hint: [component] [from-framework] [to-framework]
---
Migrate the $0 component from $1 to $2.
1. Analyze the current $1 implementation of $0
2. Create the equivalent $2 version
3. Preserve all behavior and tests
4. Update all importsRunning /migrate-component SearchBar React Vue:
$0= SearchBar$1= React$2= Vue$ARGUMENTS= SearchBar React Vue (the whole string)
Argument Hints
The argument-hint field shows in autocomplete when you type the skill name:
---
name: deploy
argument-hint: [environment]
---When you type /deploy, the CLI shows [environment] as a hint for what to type next.
Built-in Skills
Claude Code ships with five bundled skills available in every session:
These are prompt-based skills, not hard-coded commands. They give Claude detailed playbooks and let it orchestrate work using tools. You can read their source to learn how to write effective skills.
Creating Your First Skill
Step 1: Choose Location
Decide the scope:
# Personal (all your projects):
mkdir -p ~/.claude/skills/my-skill
# Project-specific (shared with team):
mkdir -p .claude/skills/my-skillStep 2: Write SKILL.md
Start simple:
---
name: explain-code
description: Explains code with visual diagrams and analogies. Use when explaining how code works or teaching about a codebase.
---
When explaining code, always:
1. **Start with an analogy** — compare to something from everyday life
2. **Draw a diagram** — use ASCII art to show data flow or structure
3. **Walk through step-by-step** — explain what each key section does
4. **Highlight a gotcha** — call out common mistakes or misconceptions
Keep explanations conversational. Use multiple analogies for complex concepts.Step 3: Test It
Invoke manually to verify:
/explain-code src/auth/middleware.tsOr trigger auto-invocation:
How does the auth middleware work?Claude should now include analogies, ASCII diagrams, and gotchas in its explanation — because your skill told it to.
Step 4: Add Supporting Files (Optional)
As your skill grows, extract detailed content into separate files:
explain-code/
├── SKILL.md # Main instructions (keep under 500 lines)
├── patterns.md # Common explanation patterns
└── examples.md # Before/after examples of good explanationsReference them from SKILL.md:
See [patterns.md](patterns.md) for common explanation patterns.
See [examples.md](examples.md) for example explanations.Claude will read these files when it needs them, keeping the base skill lightweight.
Real-World Examples
Here are production-ready skills covering the most common use cases.
Deploy Skill (Task, Protected)
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
allowed-tools: Bash(npm *, git *)
argument-hint: [environment]
---
Deploy the application to $0:
1. **Pre-flight checks**
- Verify branch is main: `git branch --show-current`
- Ensure working directory is clean: `git status`
- Pull latest: `git pull origin main`
2. **Test**
- Run full test suite: `npm test`
- All tests must pass before proceeding
3. **Build**
- Run production build: `npm run build`
- Verify build output exists
4. **Deploy**
- Tag release: `git tag -a v$(date +%Y.%m.%d) -m "Release"`
- Push tag: `git push origin --tags`
- Deploy: `npm run deploy:$0`
5. **Verify**
- Check health endpoint
- Monitor logs for errors
- Run smoke tests
Each step must succeed before proceeding to the next.
If any step fails, stop and report the error.Key choices: disable-model-invocation: true prevents accidental deployments. allowed-tools: Bash(npm *, git *) restricts what commands Claude can run.
Code Review Skill (Reference, Auto-Invoked)
---
name: code-reviewer
description: Expert code review. Use when reviewing code for quality, security, and maintainability.
allowed-tools: Read, Grep, Glob
---
You are a senior code reviewer. Analyze the code with this checklist:
**Critical (must fix):**
- Security vulnerabilities (XSS, SQL injection, auth bypasses)
- Data loss risks
- Race conditions
**Major (should fix):**
- Performance problems (O(n²) where O(n) is possible)
- Missing error handling on external calls
- DRY violations (duplicated logic)
- Unclear naming or confusing control flow
**Minor (consider):**
- Style inconsistencies
- Missing edge case tests
- Overly complex one-liners
**Output format:**
For each finding:
- Severity (Critical / Major / Minor)
- File and line number
- What’s wrong
- How to fix it (with code example)
End with a summary: safe to merge, needs changes, or needs major rework.This skill uses allowed-tools: Read, Grep, Glob — read-only tools. Claude can explore the code but can’t accidentally modify it during review.
PR Summary Skill (Dynamic Context Injection)
---
name: pr-summary
description: Summarize the current pull request with live GitHub data
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---
## Live PR Data
- Diff: !`gh pr diff`
- Comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
- PR metadata: !`gh pr view --json title,body,author,labels`
## Your Task
Summarize this pull request in 2–3 paragraphs:
1. **What changed** — high-level summary of the diff
2. **Why** — motivation based on PR description and comments
3. **Risk assessment** — what could break, what needs careful review
Highlight any files with >100 lines changed as needing extra attention.The !`gh pr diff` commands execute before Claude sees the prompt. Claude receives the actual diff, comments, and metadata — fully rendered with real data. The context: fork keeps the (potentially massive) diff out of your main conversation window.
Test Coverage Skill (Forked Subagent)
---
name: test-gaps
description: Analyze test coverage and identify gaps
context: fork
agent: Explore
allowed-tools: Read, Grep, Glob, Bash(npm test*, npx jest*)
---
Analyze test coverage for $ARGUMENTS (or the entire project if no args):
1. **Run coverage**: `npx jest --coverage --silent`
2. **Parse report**: Find files below 80% coverage
3. **Identify gaps**: What functions/branches are untested?
4. **Prioritize**: Rank by risk (auth > utils, write paths > read paths)
Output:
- Top 5 files needing tests, with specific functions to test
- For each, suggest 2–3 test cases with expected behavior
- Estimated effort: quick (<30min), medium (<2hr), or deep (>2hr)Blog Post Skill (Complex Multi-Step Workflow)
---
name: create-post
description: Create a new Ghost blog post with the full workflow
disable-model-invocation: true
allowed-tools: Read, Write, Bash(python3 *)
argument-hint: [title]
---
Create a new blog post: "$ARGUMENTS"
Follow the full 11-step workflow from CLAUDE.md:
1. **Gather content**: title, slug, excerpt, featured image, tag
2. **SEO fields**: meta title, meta description, OG image
3. **Signup card**: append the standard card
4. **Create as draft**: via Ghost Admin API, share preview link
5. **Iterate**: get feedback, make changes
6. **Publish + email**: set status to published, email all subscribers
7. **Update Start Here**: add to the correct section
8. **Cross-link**: add related reading links
9. **LinkedIn draft**: write a standalone companion post
10. **Cleanup**: delete temp files
11. **Update docs**: update ctx.md, commit, push
Always confirm slug, tag, and image with the user before creating.
Never publish without explicit approval.This skill encapsulates an entire workflow. By using disable-model-invocation: true, it only runs when you explicitly type /create-post My Article Title.
Advanced Patterns
Hooks Inside Skills
Skills can define hooks scoped to their lifecycle. The hooks fire only while the skill is active:
---
name: safe-db-query
description: Execute read-only database queries
allowed-tools: Bash
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-readonly.sh"
---
Execute SELECT queries to analyze data.
Only read operations are allowed — the hook validates every command.
$ARGUMENTSThe hook runs validate-readonly.sh before every Bash command. If the script exits non-zero (e.g., it detects a DELETE or UPDATE), the command is blocked. This gives you deterministic safety guarantees beyond what prompt instructions alone can provide.
MCP Server Integration
Skills can use MCP (Model Context Protocol) server tools. MCP tools follow the naming pattern mcp__<server>__<tool>:
---
name: github-search
description: Search GitHub repositories, issues, and code
allowed-tools: mcp__github__*, Read
---
Search GitHub for: $ARGUMENTS
Available tools:
- mcp__github__search_repositories: Find repos by keyword
- mcp__github__search_code: Find code snippets
- mcp__github__get_issue: Get issue details by number
Report findings with links to relevant repositories and files.The mcp__github__* wildcard grants access to all tools from the GitHub MCP server.
Tool Restriction Patterns
Control what Claude can do with precision:
# Read-only exploration
allowed-tools: Read, Grep, Glob
# Code generation with test safety
allowed-tools: Read, Write, Edit, Bash(npm test*)
# Git-only operations
allowed-tools: Bash(git *)
# Specific command patterns
allowed-tools: Bash(python3 scripts/*), Read
# MCP tools with wildcards
allowed-tools: mcp__github__*, mcp__linear__create_issue
# Restrict subagent types
allowed-tools: Agent(worker, researcher), ReadExtended Thinking
To enable extended thinking (deep reasoning mode) within a skill, include the word ultrathink anywhere in the skill content:
---
name: architecture-review
description: Deep architectural analysis with extended reasoning
---
Use ultrathink to deeply analyze the architecture of $ARGUMENTS.
Consider:
- Component dependencies and coupling
- Data flow and state management
- Scalability bottlenecks
- Security boundariesSkill-Scoped Permissions
Control which skills Claude can invoke via your settings.json:
{
"permissions": {
"allow": ["Skill(fix-issue)", "Skill(deploy *)"],
"deny": ["Skill(destructive *)"]
}
}Use Skill(name) for exact match, Skill(name *) for prefix match. To disable all skills: "deny": ["Skill"].
Skills vs CLAUDE.md vs Hooks: The Decision Framework
These three systems serve different purposes. Here’s when to use each:
The decision framework:
- If it’s a rule that should always apply (coding standards, naming conventions, build commands) → CLAUDE.md
- If it’s a workflow you trigger when needed (deploy, review, create PR) → Skill
- If it must happen deterministically every time (format after edit, validate before commit) → Hook
- If Claude needs to know about it but only sometimes (legacy system context, API patterns) → Hidden Skill (
user-invocable: false)
They’re complementary. CLAUDE.md tells Claude how to behave. Skills tell Claude what to do. Hooks enforce guardrails. A well-configured project uses all three.
Best Practices
- Write clear descriptions. The description is the most important field. Claude uses it to decide when to load your skill. Be specific: "Deploy the application to production" not "Deploy tool".
- Restrict tools to minimum necessary. A code review skill only needs
Read, Grep, Glob. A deploy skill needsBash(npm *, git *). Don’t grant full access when you don’t need it. - Use disable-model-invocation for side effects. Anything that deploys, commits, sends messages, or modifies external state should require explicit invocation.
- Keep SKILL.md under 500 lines. Extract detailed reference material into supporting files. Claude reads them on-demand.
- Use forked context for heavy operations. Test suites, deep research, large diffs — anything that produces verbose output belongs in a
context: forkskill. - Number your steps. Task skills are clearer when steps are explicitly numbered. Claude follows numbered sequences more reliably.
- Include failure handling. Tell Claude what to do when a step fails. "If tests fail, stop and report the errors" prevents runaway execution.
- Test with manual invocation first. Before relying on auto-invocation, test with
/skill-nameto verify the skill works as expected.
Common Gotchas
- Skills are guidance, not enforcement. Claude tries to follow them, but there’s no guarantee. If you need deterministic behavior, use hooks.
- Descriptions consume context. Every skill’s description is always loaded. Too many skills with long descriptions eat into your context window. Keep descriptions concise.
- Auto-invocation is probabilistic. Claude uses the description to decide. Phrasing matters. If your skill isn’t being auto-invoked, try rewording the description with keywords users would naturally say.
- Forked skills have no conversation history. A
context: forkskill runs in isolation. It can’t reference what you discussed earlier. Write the skill content to be fully self-contained. - Subagents can’t nest. A skill running in a forked subagent cannot spawn another subagent. Keep this in mind when designing complex workflows.
- Plugin skills can’t use hooks. For security reasons, plugin-provided skills cannot define hooks, MCP servers, or permission modes.
- User skills don’t sync. Skills in
~/.claude/skills/are local to your machine. They won’t be on your other workstation unless you sync them manually. - YAML formatting is strict. Trailing commas, wrong indentation, or unquoted special characters in frontmatter will cause parse errors. Validate your YAML.
Quick Reference
Skills are one of Claude Code’s most powerful features — and one of its most underused. Start with one simple skill for a workflow you repeat often. Once you see how much time it saves, you’ll never go back to explaining the same process twice.