Skip to main content

Claude Code Skills

Create reusable workflows with just-in-time loading, bundled scripts, and automatic invocation

60 minutes
8 min read
Updated February 11, 2026

Claude Code Skills

Skills are Claude Code's reusable workflow engine. Unlike CLAUDE.md (which loads into every session), skills load just-in-time — Claude sees only the name and description until a skill is needed, then loads the full instructions on demand. This keeps your context window clean while giving Claude access to dozens of capabilities.

A skill can be as simple as a set of instructions or as powerful as a multi-file package with bundled scripts, templates, and reference docs.

How Skills Work
Skills load progressively — metadata first, full content only when needed

Quick Start

  1. 1

    Create the skill directory

    Bash
    mkdir -p .claude/skills/fix-issue
  2. 2

    Write SKILL.md

    Create .claude/skills/fix-issue/SKILL.md:

    YAML
    ---
    name: fix-issue
    description: "Fixes a GitHub issue by reading it, locating the code, implementing a fix, and writing tests."
    ---
    Fix GitHub issue #$ARGUMENTS:
    1. Read the issue description with `gh issue view $ARGUMENTS`
    2. Locate the relevant code
    3. Implement a fix following project conventions
    4. Write tests covering the fix
    5. Create commit: "fix: Description (closes #$ARGUMENTS)"
  3. 3

    Use it

    Invoke directly:

    Bash
    /fix-issue 1234

    Or let Claude invoke it automatically — if you say "there's a bug in issue 1234," Claude recognizes the skill's description matches and loads it.


Where Skills Live

Where you store a skill determines who can use it:

LocationPathApplies To
EnterpriseManaged settingsAll users in your organization
Personal~/.claude/skills/skill-name/SKILL.mdAll your projects
Project.claude/skills/skill-name/SKILL.mdThis project only
Pluginplugin/skills/skill-name/SKILL.mdWhere plugin is enabled

Priority (highest to lowest): Enterprise > Personal > Project. If a skill and a legacy command (.claude/commands/) share the same name, the skill takes precedence.

Backward Compatibility

Your .claude/commands/ files still work and support the same frontmatter. The mapping is straightforward:

Legacy CommandsSkills
.claude/commands/review.md.claude/skills/review/SKILL.md
~/.claude/commands/standup.md~/.claude/skills/standup/SKILL.md
.claude/commands/git/squash.md.claude/skills/git-squash/SKILL.md

Both create /review, /standup, /git-squash and work the same way. Skills add the ability to bundle supporting files alongside SKILL.md.


Skill Anatomy

Every skill is a directory with SKILL.md as the entrypoint:

Bash
my-skill/
├── SKILL.md # Main instructions (required)
├── template.md # Template for Claude to fill in
├── examples/
│ └── sample.md # Example output showing expected format
└── scripts/
└── validate.sh # Script Claude can execute

SKILL.md Format

Two parts: YAML frontmatter (between --- markers) and markdown content with instructions.

YAML
---
name: deploy
description: Deploy the application to production
disable-model-invocation: true
allowed-tools: Bash(npm *), Bash(git *)
---
Deploy $ARGUMENTS to production:
1. Run `npm test` — if any test fails, STOP
2. Run `npm run build`
3. Run `npm run deploy:prod`
4. Verify the deployment succeeded
5. Report the deployment URL
IMPORTANT: Get confirmation before deploying.
NEVER: Deploy if tests are failing.

Frontmatter Reference

All fields are optional. Only description is recommended so Claude knows when to use the skill.

FieldDescriptionDefault
nameDisplay name and /slash-command. Lowercase letters, numbers, hyphens (max 64 chars). Falls back to directory name.Directory name
descriptionWhat the skill does and when to use it. Claude uses this to decide when to load the skill automatically.First paragraph of content
argument-hintHint shown during autocomplete. e.g. [issue-number] or [filename] [format].None
disable-model-invocationSet true to prevent Claude from auto-loading this skill. User must invoke with /name.false
user-invocableSet false to hide from the / menu. Use for background knowledge Claude should apply automatically.true
allowed-toolsTools Claude can use without asking permission when this skill is active.None
modelModel to use when this skill is active.Inherited
contextSet to fork to run in an isolated subagent context.Inline
agentWhich subagent type to use when context: fork is set (Explore, Plan, general-purpose, or custom).general-purpose
hooksHooks scoped to this skill's lifecycle.None

Controlling Who Invokes a Skill

By default, both you and Claude can invoke any skill. Two frontmatter fields restrict this:

FrontmatterYou Can InvokeClaude Can InvokeWhen Loaded
(default)YesYesDescription always in context, full skill loads when invoked
disable-model-invocation: trueYesNoDescription not in context, loads only when you invoke
user-invocable: falseNoYesDescription always in context, loads when Claude decides

Use disable-model-invocation: true for workflows with side effects — deploy, commit, send messages. You don't want Claude deciding to deploy because your code looks ready.

Use user-invocable: false for background knowledge — legacy system context, domain expertise, coding conventions. Claude should know this when relevant, but /legacy-context isn't a meaningful action for users.


Arguments and Substitutions

Skills support several dynamic placeholders:

VariableDescriptionExample
$ARGUMENTSAll arguments passed when invoking/fix-issue 1234 → "1234"
$ARGUMENTS[N]Specific argument by index (0-based)$ARGUMENTS[0] → first arg
$NShorthand for $ARGUMENTS[N]$0 → first arg, $1 → second
$${CLAUDE_SESSION_ID}Current session ID for logging/trackinglogs/abc123.log

Positional arguments example:

YAML
---
name: migrate-component
description: Migrate a component from one framework to another
---
Migrate the $0 component from $1 to $2.
Preserve all existing behavior and tests.
Bash
/migrate-component SearchBar React Vue

If a skill doesn't include $ARGUMENTS, arguments are appended as ARGUMENTS: <value> automatically.


Types of Skills

Reference Skills (Background Knowledge)

Add knowledge Claude applies to current work — conventions, patterns, style guides. These run inline alongside your conversation.

YAML
---
name: api-conventions
description: API design patterns for this codebase
user-invocable: false
---
When writing API endpoints:
- Use RESTful naming conventions
- Return consistent error formats using ApiResponse<T>
- Validate all inputs with Zod schemas
- Include authentication middleware on all routes

Task Skills (Workflows)

Step-by-step instructions for specific actions. Often invoked manually with /skill-name.

YAML
---
name: pr-ready
description: Prepare changes for a pull request
disable-model-invocation: true
---
Prepare the current branch for PR:
1. Run `npm run lint` — fix any issues
2. Run `npm test` — all must pass
3. Run `npm run build` — must succeed
4. Write a commit message following conventional commits
5. Push to remote with `git push -u origin HEAD`
6. Create PR with `gh pr create`
IMPORTANT: Stop and report if any step fails.

Real-World Examples

Development Workflow

Code Review.claude/skills/review/SKILL.md:

YAML
---
name: review
description: Review current changes for bugs, security issues, and code quality
disable-model-invocation: true
allowed-tools: Bash(git diff*), Read, Grep, Glob
---
Review the current changes:
1. Run `git diff` to see all changes
2. For each file changed, analyze for:
- Logic errors and edge cases
- Security vulnerabilities (injection, auth, secrets)
- Performance issues (N+1 queries, memory leaks)
- Missing tests for new behavior
3. Provide feedback:
## Review Summary
**Status:** Approved / Needs Changes
### Issues Found
- **[severity]** Issue description (file:line)
### Suggestions
- Improvement suggestions
IMPORTANT: Be specific with file paths and line numbers.
YOU MUST: Explain *why* something is an issue, not just *what*.

Bug Investigation.claude/skills/investigate/SKILL.md:

YAML
---
name: investigate
description: Investigate a bug by understanding, reproducing, and analyzing root cause
disable-model-invocation: true
---
Investigate: $ARGUMENTS
## Understand
1. Parse the bug description
2. Identify expected vs actual behavior
## Reproduce
1. Find reproduction steps
2. Add logging if needed to trace the issue
## Analyze
1. Search codebase for related code
2. Check git history for recent changes to affected files
3. Identify root cause
## Report
- **Behavior:** What happens
- **Expected:** What should happen
- **Root Cause:** Technical explanation
- **Files Affected:** List with line numbers
- **Proposed Fix:** Approach and risk assessment
DO NOT fix yet — wait for approval.

Git Workflow

Smart Commit.claude/skills/commit/SKILL.md:

YAML
---
name: commit
description: Stage changes and create a well-formatted conventional commit
disable-model-invocation: true
---
Create a commit for the current changes:
1. Run `git status` and `git diff` to understand all changes
2. Stage relevant files (not .env or credentials)
3. Write a commit message:
- Type: feat/fix/refactor/docs/test/chore
- Scope: affected area in parentheses
- Subject: imperative, lowercase, no period
- Body: explain *why*, not *what*
4. Create the commit
5. Show `git log --oneline -3` to confirm
Format: `type(scope): subject`
Example: `fix(auth): handle expired refresh tokens`

Daily Workflow

Standup Summary~/.claude/skills/standup/SKILL.md:

YAML
---
name: standup
description: Generate a standup summary from yesterday's git activity
disable-model-invocation: true
---
Generate standup summary:
1. Get yesterday's commits:
`git log --since="yesterday" --author="$(git config user.name)" --oneline`
2. Check current branch and status
3. Look for any failing tests
## Standup — [Today's Date]
### Yesterday
- [List from commits]
### Today
- [Current branch/task]
### Blockers
- [Any issues found]

Code Generation

API Endpoint.claude/skills/api-endpoint/SKILL.md:

YAML
---
name: api-endpoint
description: Generate a new API endpoint following project conventions
disable-model-invocation: true
---
Create an API endpoint for: $ARGUMENTS
## Our Patterns
- Inputs validated with Zod
- Responses use ApiResponse<T>
- Authentication via middleware
- Proper error handling with status codes
## Steps
1. Create src/app/api/$0/route.ts
2. Define request/response Zod schemas
3. Add authentication check
4. Implement business logic
5. Add error handling
6. Create test file
IMPORTANT: Follow existing patterns in src/app/api/

Advanced Patterns

Dynamic Context Injection

The !`command` syntax runs shell commands before the skill content is sent to Claude. The output replaces the placeholder, so Claude receives real data.

YAML
---
name: pr-summary
description: Summarize changes in a pull request
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---
## 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: what changed, why, and any concerns.

When this skill runs, each !`command` executes immediately, output replaces the placeholder, and Claude receives the fully-rendered prompt with actual PR data.

Running Skills in a Subagent

Add context: fork to run a skill in an isolated context. The skill content becomes the prompt driving the subagent — it won't have access to your conversation history.

YAML
---
name: deep-research
description: Research a topic thoroughly across the codebase
context: fork
agent: Explore
---
Research $ARGUMENTS thoroughly:
1. Find relevant files using Glob and Grep
2. Read and analyze the code
3. Map dependencies and relationships
4. Summarize findings with specific file references

The agent field determines the execution environment. Options: Explore, Plan, general-purpose, or any custom subagent from .claude/agents/.

Bundling Scripts

Skills can include executable scripts for deterministic tasks. The script does the heavy lifting while Claude handles orchestration.

Bash
codebase-visualizer/
├── SKILL.md
└── scripts/
└── visualize.py

SKILL.md:

YAML
---
name: codebase-visualizer
description: Generate an interactive tree visualization of the codebase
allowed-tools: Bash(python *)
---
Generate an interactive HTML tree view of the project structure:
```bash
python ~/.claude/skills/codebase-visualizer/scripts/visualize.py .
```
This creates `codebase-map.html` and opens it in your browser.

This pattern works for any visual output: dependency graphs, test coverage reports, API documentation, or database schema diagrams.

Supporting Files

Keep SKILL.md focused (under 500 lines) and move detailed reference material to separate files. Claude loads them only when needed.

Bash
api-generator/
├── SKILL.md # Overview and navigation
├── reference.md # Detailed API spec (loaded on demand)
├── examples.md # Example outputs
└── templates/
└── route-template.ts # Boilerplate template

Reference supporting files from SKILL.md:

Markdown
## Additional resources
- For complete API details, see [reference.md](reference.md)
- For usage examples, see [examples.md](examples.md)

Best Practices

Writing Effective Descriptions

The description field is how Claude decides whether to load your skill. Write it like a search query match:

YAML
# Good — specific triggers
description: "Fixes a GitHub issue by reading it, finding the code, and implementing a fix with tests. Use when someone mentions a bug or issue number."
# Bad — too vague
description: "Helps with issues"

Context Efficiency

  • Skill descriptions use ~50 tokens each during metadata scanning
  • Full skill content loads only when invoked (typically under 5k tokens)
  • The description budget scales at 2% of the context window (fallback: 16,000 chars)
  • Override with SLASH_COMMAND_TOOL_CHAR_BUDGET env var if you have many skills

Structure and Safety

  1. Use sections — Break skills into Understanding, Steps, Output Format, and Safety Checks
  2. Include safety rails — Add IMPORTANT: and NEVER: directives for destructive operations
  3. Define output format — Tell Claude exactly what the result should look like
  4. Handle errors — Tell Claude what to do when a step fails (stop? retry? report?)

Invocation Control

  • Destructive actions (deploy, delete, send): Use disable-model-invocation: true
  • Background knowledge (conventions, domain context): Use user-invocable: false
  • General workflows (review, research): Leave defaults — let both you and Claude invoke

Restrict Tools

Limit what Claude can do during a skill for safety:

YAML
---
name: safe-reader
description: Read and analyze files without making changes
allowed-tools: Read, Grep, Glob
---

Permission Control

Control which skills Claude can invoke through permission rules:

Bash
# Allow only specific skills
Skill(commit)
Skill(review-pr *)
# Deny specific skills
Skill(deploy *)

Syntax: Skill(name) for exact match, Skill(name *) for prefix match with any arguments.


Sharing Skills

With Your Team

Commit project skills to git:

Bash
git add .claude/skills/
git commit -m "feat: add team workflow skills"

As a Plugin

Package skills with other extensions in a plugin's skills/ directory. Plugin skills use plugin-name:skill-name namespacing to avoid conflicts.

Community Skills

Skills follow the Agent Skills open standard, which works across multiple AI tools. Browse community skills at github.com/anthropics/skills.


Troubleshooting

Skill Not Triggering

  1. Check the description includes keywords users would naturally say
  2. Verify the skill appears when you ask "What skills are available?"
  3. Try invoking directly with /skill-name
  4. Check that disable-model-invocation isn't set to true

Skill Triggers Too Often

  1. Make the description more specific
  2. Add disable-model-invocation: true for manual-only invocation

Skill Not Found

  • Verify SKILL.md exists in the skill directory
  • Check directory location (.claude/skills/name/SKILL.md or ~/.claude/skills/name/SKILL.md)
  • For legacy commands: file exists in .claude/commands/ with .md extension
  • Filename/directory matches the command name (kebab-case)

Too Many Skills Excluded

If Claude doesn't see all your skills, the description budget may be exceeded:

  • Run /context to check for warnings
  • Set SLASH_COMMAND_TOOL_CHAR_BUDGET to a higher value
  • Shorten descriptions or consolidate related skills

Quick Reference

Skill Directory Structure

Bash
.claude/skills/my-skill/
├── SKILL.md # Required — main instructions
├── reference.md # Optional — detailed docs
├── templates/ # Optional — boilerplate files
├── examples/ # Optional — example outputs
└── scripts/ # Optional — executable scripts

Minimal SKILL.md Template

YAML
---
name: skill-name
description: What this skill does and when to use it
---
Instructions for Claude when this skill is invoked.
1. First step
2. Second step
3. Third step
## Output Format
Expected output format.
IMPORTANT: Critical rules.
NEVER: Prohibited actions.

Keyword Directives

KeywordEffect
IMPORTANT:High priority instruction
YOU MUST:Required behavior
NEVER:Prohibited action
CRITICAL:Absolute requirement

Next Steps

  1. Start with one skill — automate something you do weekly
  2. Test both invocation paths — try /skill-name and natural language
  3. Add supporting files — templates and scripts for complex workflows
  4. Share with your team — commit to .claude/skills/ and push

Related Topics:

Share this article