Claude Code Skills turn multi-step workflows into one-line slash commands. Type /review and Claude runs a structured code review against your team’s checklist. Type /deploy and it walks through your pre-deployment checklist, checks environment variables, and confirms rollback procedures — without you writing a single line of automation code.
This guide is the complete technical reference for authoring Claude Code skills in 2026: what the skill file format looks like, every frontmatter option, how to restrict tool access, how to package skills for distribution, and five production-quality examples you can copy directly into your project.
If you have never used skills before, expect to have your first working skill in under ten minutes. If you are building skills for your team or for public distribution, the later sections on plugin packaging and the Skills vs. Commands vs. Subagents decision tree will be useful.
What Are Claude Code Skills
A Claude Code skill is a Markdown file that Claude Code loads as a system prompt when you invoke the corresponding slash command. The file defines the skill’s name (which becomes the /command), a description used for autocomplete and autonomous invocation, and the body of instructions Claude will follow.
From Claude Code’s perspective, invoking a skill is identical to placing those instructions at the top of the conversation. Skills are not scripts — they do not execute code themselves. They direct Claude to execute code on your behalf, using whichever tools (Bash, file reading and writing, web search, MCP servers) it has access to.
This distinction matters. You are writing instructions for an AI agent, not a shell script. The power comes from combining natural-language task description with the full tool capabilities of Claude Code — and the result can outperform a brittle shell script in many real-world workflows because Claude can reason about errors, adapt to context, and ask for clarification when something is ambiguous.
Where Skills Live
Skills are discovered from two directories:
~/.claude/skills/ # Global — available in every project
.claude/skills/ # Project-scoped — only this project
Each skill is either a single Markdown file or a directory:
.claude/skills/
review.md # Single-file skill (simple cases)
deploy/ # Directory skill (complex workflows)
SKILL.md # Required entry point
checklist.md # Supporting reference document
rollback.md # Additional reference
examples/
staging.md
production.md
When a project-scoped skill and a global skill share the same name, the project-scoped skill wins. This lets projects override shared defaults without touching your global configuration.
Two Invocation Patterns
Skills can be triggered in two ways:
Manual invocation: You type /skill-name in the Claude Code interface. Claude loads the skill and executes it immediately.
Autonomous invocation: Claude decides on its own to load a skill based on the task at hand. This is driven by the description frontmatter field. If Claude determines that a skill’s description matches what it is trying to do, it invokes the skill without being prompted.
Autonomous invocation is what makes skills genuinely useful in agentic workflows. A skill with the description "Use when writing database migrations to check for backward compatibility" will be called automatically when Claude writes migrations. But this only works if the description is specific enough to function as a routing rule — vague descriptions like “helps with code” will be ignored.
Skill Anatomy: Frontmatter and Body
Every skill file has the same structure: YAML frontmatter followed by the instruction body.
---
name: review
description: Review the current branch's changes for correctness,
security issues, and style violations. Use before
committing or opening a pull request.
---
Review all modified files in the current session.
For each file:
- Check for null pointer dereferences and unhandled error returns
- Verify that external inputs are validated before use
- Confirm that any new dependencies are pinned to specific versions
- Flag any hardcoded credentials or secrets
Output a numbered list organized by severity: Critical, Warning, Info.
For each issue, include the file and line number, a one-line description,
and a suggested fix.
If a file has no issues, skip it.
End with a one-line summary: "No issues found" or "N issues found across M files."
The frontmatter is processed by Claude Code to register the skill. The body is loaded as a system prompt when the skill is invoked.
Writing Instructions That Work
The most common authoring mistake is writing skills like conversational prompts. Skills are operational instructions, not requests.
Weak (conversational):
Could you please help review my code? I'd really appreciate if you
could look for any problems and let me know what you think.
Strong (operational):
Review all modified files in the current session.
For each file:
- Check for unhandled error returns and null dereferences
- Verify external inputs are validated before use
Output a numbered list. Skip clean files. End with a one-line summary.
Three rules that improve instruction quality consistently:
- Use imperative verbs. “Review”, “Output”, “Check”, “Skip”, “Flag” — not “could you” or “please.”
- Specify output format explicitly. If you want a numbered list, say numbered list. If you want JSON, show the schema.
- Handle edge cases. What should Claude do if there is nothing to review? If a command fails? Silence on edge cases leads to improvised, inconsistent behavior.
Frontmatter Options Reference
The frontmatter block controls how the skill is registered and what constraints it operates under.
name (required)
name: review
Becomes the slash command. name: review → /review. Use lowercase, hyphens allowed: name: pre-commit-check → /pre-commit-check.
Keep names short and memorable. You will be typing them constantly.
description (required)
description: Review the current branch for correctness and security issues.
Use before committing or opening a pull request.
Serves two purposes: it appears in the / autocomplete list, and it tells Claude when to invoke this skill autonomously. Write it as both a human-readable description and an agent routing rule.
Multi-line descriptions are supported via YAML block scalar syntax. Longer descriptions give Claude more context for autonomous routing — but keep them to two or three sentences. Beyond that, you are better off putting the context in the skill body.
allowed-tools (optional)
allowed-tools:
- Bash
- Read
- Write
Restricts which tools the skill can use. When allowed-tools is specified, the skill can only use the listed tools — all others are blocked for the duration of that skill invocation.
This is a security and predictability feature. A skill that only reads code and outputs findings should not be calling Bash or making network requests. Specifying allowed-tools makes this explicit and enforced.
Available tool names include:
| Tool | What it does |
|---|---|
Bash | Execute shell commands |
Read | Read files |
Write | Create or overwrite files |
Edit | Make targeted edits to files |
WebSearch | Search the web |
WebFetch | Fetch content from a URL |
mcp__* | Any MCP server tool (use the full tool name) |
To allow a specific MCP tool: mcp__github__create_pull_request. To allow all tools from an MCP server: mcp__github__* (glob syntax supported).
model (optional)
model: claude-opus-4-5
Specifies which Claude model the skill uses. If omitted, the skill uses whatever model the session is using.
You might want to override the model for specific use cases:
- Use a faster model (Haiku) for high-frequency utility skills that do simple tasks
- Use a more capable model (Opus) for deep analysis skills that need more reasoning
tools (optional, alias for allowed-tools)
tools:
- Read
- Bash
Identical to allowed-tools. Both work; allowed-tools is the canonical form in official docs.
disallowed-tools (optional)
disallowed-tools:
- Bash
- Write
The inverse of allowed-tools. Instead of an allowlist, specifies which tools are blocked. The skill can use any tool except the listed ones.
Use this when you want to grant broad access with specific exceptions. “Everything except network requests” is easier to express as a disallowlist.
Only one of allowed-tools or disallowed-tools should be set for a given skill — not both.
Creating Your First Skill: Step by Step
Step 1: Create the skills directory
# For a project-scoped skill
mkdir -p .claude/skills
# For a global skill
mkdir -p ~/.claude/skills
Step 2: Write the skill file
Create .claude/skills/review.md:
---
name: review
description: Review staged changes for correctness, security, and style
issues. Use before committing or opening a pull request.
allowed-tools:
- Bash
- Read
---
Review the staged changes in the current repository.
Run `git diff --staged` to get the diff. If there are no staged changes,
run `git diff HEAD` instead.
For each changed file, check:
**Correctness**
- Logic errors, off-by-one bugs, incorrect conditionals
- Unhandled error paths, missing null checks
- Race conditions in concurrent code
**Security**
- Hardcoded credentials, API keys, or tokens
- Unvalidated external inputs
- SQL or command injection patterns
- Insecure defaults (e.g., debug mode enabled, permissive CORS)
**Style**
- Inconsistencies with the surrounding code
- Missing or incorrect comments on public APIs
- Overly complex expressions that should be broken down
Output format:
- Group findings by severity: Critical / Warning / Info
- Each finding: file:line — brief description — suggested fix
- If a file is clean, skip it
- End with one line: "N issues found" or "No issues found"
Do not suggest changes for lines not in the diff.
Step 3: Verify the skill is available
Start or restart a Claude Code session in the project directory. Type / in the interface — your skill should appear in the autocomplete list with the description you wrote.
Step 4: Invoke and iterate
Run /review. Check whether the output matches your expectations. Common issues on the first iteration:
- Output is too verbose: Add explicit output constraints (“keep descriptions under 20 words”)
- Claude checks files outside the diff: Make the scope more explicit (“only files that appear in
git diff --staged”) - Edge cases are handled badly: Add explicit edge case instructions (“if no staged changes exist, say so and stop”)
Expect two or three iterations before a skill feels right. The best skills in the community got there through repeated refinement, not a perfect first draft.
Step 5: Commit to your repository
git add .claude/skills/
git commit -m "Add code review skill"
Skills in .claude/skills/ belong in your repository. That is the point — everyone on the team gets the same workflows automatically.
5 Real-World Skill Examples
1. Code Review
The most common skill. The key is specificity about scope and output format.
---
name: review
description: Review staged or PR changes for bugs, security issues, and
style violations. Run before committing or requesting review.
allowed-tools:
- Bash
- Read
---
Run `git diff --staged` to get staged changes. If nothing is staged,
run `git diff HEAD~1` instead.
Check each changed file for:
1. **Bugs**: null dereferences, off-by-one errors, unhandled exceptions,
race conditions, incorrect boolean logic
2. **Security**: hardcoded credentials, unvalidated inputs, injection
patterns, insecure defaults, overly permissive access
3. **Performance**: N+1 queries, unnecessary loops, memory leaks,
blocking calls in async contexts
4. **Maintainability**: magic numbers, missing error messages, functions
over 50 lines without justification
Output structure:
- Section header: filename (relative path)
- Numbered findings with severity [CRIT / WARN / INFO]
- Each finding: line range — issue description — fix suggestion
- Skip files with no findings
- Final line: "Review complete. N critical, M warnings, K info."
2. Deployment Workflow
A deployment skill works best as a directory, because the checklist and rollback procedure benefit from being in separate files.
.claude/skills/deploy/
SKILL.md
pre-deploy-checklist.md
rollback.md
SKILL.md:
---
name: deploy
description: Run the deployment workflow for this project. Use when
deploying to staging or production environments.
allowed-tools:
- Bash
- Read
- Write
---
Before starting, read `pre-deploy-checklist.md` and confirm each item
is satisfied.
Determine the deployment target by asking: staging or production?
**For staging:**
1. Run `npm run test` — abort if any tests fail
2. Run `npm run build` — abort on error
3. Run `./scripts/deploy.sh staging`
4. Verify deployment at $STAGING_URL with `curl -f $STAGING_URL/health`
5. Log the deployment in `deploy-log.md`: timestamp, target, git SHA, deployer
**For production:**
1. Run the staging deployment first if not already done today
2. Run `npm run test` — abort if any tests fail
3. Confirm with the user: "Ready to deploy [git SHA] to production. Continue?"
4. Run `./scripts/deploy.sh production`
5. Verify deployment with health check
6. Log the deployment
If any step fails, follow the rollback procedure in `rollback.md`.
Never proceed past a failed step without explicit user confirmation.
pre-deploy-checklist.md:
# Pre-Deploy Checklist
Before deploying, confirm:
- [ ] All tests pass locally (`npm test`)
- [ ] No open critical issues tagged `blocks-deploy` in the issue tracker
- [ ] Environment variables are set: DATABASE_URL, API_KEY, REDIS_URL
- [ ] Database migrations are backward-compatible (old app + new DB must work)
- [ ] Monitoring and alerting are active (check Datadog/Grafana)
- [ ] The deploy window is approved (no deploys Friday 16:00–Monday 09:00)
3. Test Runner with Coverage Analysis
---
name: test
description: Run the test suite, report failures with context, and identify
coverage gaps in recently modified files.
allowed-tools:
- Bash
- Read
---
Run the project's test suite:
```bash
npm test -- --coverage 2>&1
Parse the output and report:
Failed tests (if any):
- Test name and file
- Error message and stack trace (first 10 lines only)
- The code under test (read the relevant source file)
- Likely cause and suggested fix
Coverage gaps (if test pass):
- Get recently modified files:
git diff --name-only HEAD~5 -- '*.ts' '*.js' - For each modified file, check if it has a corresponding test file
- If coverage < 80% for any modified file, flag it with the specific uncovered lines
End with:
- Test result summary: “X passed, Y failed, Z skipped”
- Coverage summary for modified files
- List of modified files with no test coverage at all (highest priority)
### 4. Database Migration Safety Check
A skill that runs before any migration to catch backward compatibility issues.
```markdown
---
name: migration-check
description: Check a new database migration file for backward compatibility
issues before applying it. Use when writing or reviewing migrations.
allowed-tools:
- Bash
- Read
---
Find the most recent migration file:
```bash
ls -t db/migrations/*.sql | head -1
Or if using a framework: ls -t db/migrate/*.rb | head -1
Read the migration file and check for:
Breaking changes (will cause errors if old app runs against new schema):
- Columns renamed or dropped
- NOT NULL columns added without a default value
- Column type changes that are not backward-compatible
- Tables dropped
- Constraints that reject existing valid data
Safety issues:
- Missing index on foreign keys
- Adding indexes on large tables without CONCURRENTLY (Postgres)
- Long-running operations that could lock the table
- No corresponding rollback (down migration)
Output:
- List each issue with: [BREAKING / RISKY / SUGGESTION]
- For breaking changes, suggest the safe migration pattern (e.g., add nullable column → backfill → add constraint → remove old column)
- If the migration is safe: “Migration looks safe. No breaking changes found.”
Do not run or apply the migration. Analysis only.
### 5. Documentation Generator
```markdown
---
name: generate-docs
description: Generate or update API documentation for modified source files.
Use after adding or changing public API functions.
allowed-tools:
- Bash
- Read
- Write
---
Find files modified since the last commit with public API changes:
```bash
git diff --name-only HEAD -- 'src/**/*.ts' 'lib/**/*.py' 'pkg/**/*.go'
For each modified file:
-
Read the source file
-
Identify public functions, methods, classes, and types (not private/internal)
-
For each public item, generate documentation following these rules:
- One-sentence description of what it does (not how)
- Parameters: name, type, description, whether optional
- Return value: type and description
- At least one usage example
- Side effects or exceptions, if any
-
Check if a corresponding doc file exists in
docs/api/- If yes: update it (preserve any manually-written context sections)
- If no: create it at
docs/api/<module-name>.md
-
Update the index at
docs/api/README.mdif new files were created
Output a summary: “Updated N files, created M new doc files.” Do not document private functions (prefixed with _ or marked @internal).
---
## Sharing Skills via Plugins and Marketplaces
A skill file you drop into `.claude/skills/` works for one project. When you want to share skills across multiple projects, across your team, or with the public, the plugin system is the right packaging format.
### What a Plugin Is
A plugin is a self-contained directory (typically a Git repository) containing skills, subagents, hooks, MCP servers, and other components. It is installed once and available in every Claude Code project.
Minimal plugin structure:
my-plugin/ .claude-plugin/ plugin.json # manifest (only file that lives here) skills/ review/ SKILL.md deploy/ SKILL.md
The manifest at `.claude-plugin/plugin.json`:
```json
{
"name": "my-plugin",
"version": "1.0.0",
"description": "Code review and deployment skills for Node.js projects",
"author": {
"name": "Your Name",
"email": "[email protected]"
}
}
Plugin CLI Commands
# Install from GitHub
claude plugin install github:username/my-plugin
# Install from a local directory
claude plugin install ./path/to/my-plugin
# List installed plugins
claude plugin list
# Update a plugin
claude plugin update my-plugin
# Remove a plugin
claude plugin remove my-plugin
Plugin vs. Loose Skills
| Situation | Use loose skills | Use a plugin |
|---|---|---|
| Single project | Yes | Overkill |
| Multiple projects, just you | Copy the directory | Yes |
| Team of 2-5 people | Git submodule | Yes |
| Public distribution | — | Yes |
| Bundle skills + hooks + MCP together | Manual | Yes |
The rule of thumb from the community: if more than two people need it, package it as a plugin.
Marketplace Distribution
Plugins can be submitted to Claude Code’s plugin marketplace. Marketplace plugins are discoverable via claude plugin search <keyword>. Submission requires a valid plugin.json manifest, a README, and review by the marketplace team.
For team distribution without marketplace involvement, host the plugin in your organization’s GitHub and point team members at the Git URL:
claude plugin install github:your-org/claude-plugins
This installs from the default branch. For version-pinned installs, specify a tag:
claude plugin install github:your-org/[email protected]
Skills vs. Commands vs. Subagents: When to Use Which
These three Claude Code extension mechanisms overlap in capability but have different optimal use cases.
Skills
Use skills when:
- The workflow is user-initiated or autonomously triggered
- The task is bounded and specific: “review this code”, “deploy to staging”
- You want the behavior available as a slash command
- The workflow needs access to the filesystem but doesn’t need persistent state
Skills are the right default for most workflow automation needs.
Commands
Commands are a simpler variant of skills — Markdown-only, no SKILL.md, no directory structure. They live in commands/ inside a plugin or .claude/commands/ in a project.
Use commands when:
- The workflow is simple enough to fit in a single file
- You do not need
allowed-toolsrestrictions - You just need a quick slash command without full skill infrastructure
Think of commands as a lightweight version of skills. When in doubt, start with a command and upgrade to a skill if you need the additional features.
Subagents
Subagents are specialized Claude instances with their own system prompts, tool access, and optionally isolated file system environments.
Use subagents when:
- The task is too complex for a single context window
- You need parallel execution (multiple subagents working simultaneously)
- The task requires isolation from the main session’s state
- You are building a multi-agent pipeline where different agents have different roles (e.g., a planner agent and an executor agent)
The key difference: skills run in the current Claude session. Subagents spin up a new Claude instance. Skills are lighter weight; subagents are more powerful and more expensive.
Decision Tree
Do you need a slash command?
└─ No → Use a hook, subagent, or direct instruction
└─ Yes →
Is it simple (under 100 lines, no tool restrictions needed)?
└─ Yes → Command
└─ No →
Does it require parallel execution or isolation?
└─ Yes → Subagent with skill invocation
└─ No → Skill
FAQ
Q: Do I need to restart Claude Code after creating a skill?
No. Claude Code discovers skills at session start. In practice, start a new session after creating or editing a skill to ensure you are seeing the latest version. Some editors with Claude Code integrations may hot-reload — check your tooling’s docs.
Q: Can a skill call another skill?
Not directly via slash commands, but you can reference another skill’s content by having Claude read the SKILL.md file. In practice, most workflows that need composition are better expressed as a single skill with clear phases, or as a plugin that includes multiple related skills.
Q: How long can a SKILL.md file be?
There is no hard limit, but skills over 400–500 lines tend to lose coherence. Claude reads the full skill body as a system prompt, but later sections receive less attention in practice. If your skill needs more content, put supporting material in separate reference files in the directory and have the SKILL.md explicitly direct Claude to read them when needed.
Q: Can I pass arguments to a skill?
Yes. When you invoke /skill-name, you can append text: /review focus on security. Claude receives both the skill instructions and your additional text. For predictable argument handling, document the expected argument format in the skill’s instruction body: “If the user specifies a focus area, limit the review to that area.”
Q: Can skills read environment variables?
Indirectly. The skill itself cannot interpolate environment variables in its Markdown. But it can instruct Claude to run echo $ENV_VAR via Bash to read them. More commonly, skills instruct Claude to check whether required environment variables are set as part of their workflow.
Q: Are skills version-controlled?
When you put skills in .claude/skills/ in your project directory, yes — they are tracked by Git like any other file. This is intentional: skill changes should go through code review like code changes.
Q: Can I use skills with Claude Code in CI?
Yes. In non-interactive mode (claude -p "..." --allowedTools Bash,Read), you can invoke skills by name if the .claude/skills/ directory is present in the repository. Some teams use skills as a structured interface to Claude’s reasoning in CI pipelines — running a /review skill as part of a pull request check, for example.
Q: What is the difference between allowed-tools in a skill and allowedTools in the CLI?
allowed-tools in SKILL.md frontmatter restricts tools for that skill invocation only — it resets after the skill completes. --allowedTools on the CLI is a session-level restriction that applies to everything in that session. Use skill-level restrictions for per-workflow control; use CLI flags for environment-level constraints (like in CI).
Summary
Claude Code skills are the right abstraction for workflow automation in AI-assisted development. They are easier to write than shell scripts, more readable than raw prompts, and they compose naturally with the rest of the Claude Code ecosystem — hooks, subagents, MCP servers, and plugins.
The pattern that works:
- Start with a single skill file, under 200 lines
- Use imperative instructions with explicit output formats
- Add
allowed-toolsto enforce what the skill can and cannot do - Put complex skills in directories with supporting reference files
- Commit skills to your repository so the whole team benefits
- Package as a plugin when it is time to share
The skills that see the most use in the community are narrow and specific. Not “do everything” — “review this diff before I commit.” Not “help with deployment” — “run through the pre-deploy checklist, abort on failure, and log the result.” Narrow scope, explicit output, clear error handling. Those three properties make the difference between a skill you forget about and one you reach for every day.
Further Reading
- AGENTS.md vs CLAUDE.md: Which One Does What — Understanding how Claude Code processes instruction files and where skills fit in
- Claude Code Hooks: Complete Reference 2026 — Event-driven automation that complements skills
- Claude Code vs Codex CLI: 2026 Comparison — How skill systems compare across AI coding tools