Claude Code skills are reusable commands you create to automate repetitive workflows. Instead of typing the same multi-step instructions every session, you define them once as a skill and invoke them with a slash command.

Type /deploy and Claude runs your deployment workflow. Type /review and it audits your code against your project’s standards. Type /fix-issue 423 and it reads the GitHub issue, implements a fix, writes tests, and commits.

Skills are markdown files with optional YAML frontmatter. They’re simple to write, and they make Claude Code significantly more useful for real workflows.

How Skills Work

A skill is a directory containing a SKILL.md file:

.claude/skills/my-skill/
└── SKILL.md

The SKILL.md file has two parts:

  1. Frontmatter (optional) — YAML configuration between --- markers that controls when and how the skill runs
  2. Body — Markdown instructions that Claude follows when the skill is invoked

When you type /my-skill, Claude loads the instructions and follows them. When a skill has a description in its frontmatter, Claude can also auto-invoke it when your request matches — without you typing the command.

Creating Your First Skill

Project-Level Skill

Create a skill that’s specific to one project:

mkdir -p .claude/skills/commit

Write .claude/skills/commit/SKILL.md:

---
name: commit
description: Stage changes, write a conventional commit message, and push
disable-model-invocation: true
---

1. Run `git status` to see all changes
2. Run `git diff` to understand what changed
3. Stage the appropriate files (not unrelated changes)
4. Write a commit message following conventional commits:
   - feat: for new features
   - fix: for bug fixes
   - docs: for documentation
   - refactor: for code restructuring
   - test: for adding tests
5. Commit and push to the current branch

Now type /commit in any Claude Code session within this project.

Personal Skill (Global)

Create a skill available across all your projects:

mkdir -p ~/.claude/skills/explain

Write ~/.claude/skills/explain/SKILL.md:

---
name: explain
description: Explains code with analogies and diagrams. Use when someone asks how code works.
---

When explaining code:

1. Start with a one-sentence summary of what it does
2. Draw an ASCII diagram showing the flow or structure
3. Walk through the key parts step by step
4. Highlight one common mistake or misconception

This skill is available in every project on your machine.

Frontmatter Reference

All frontmatter fields are optional:

---
name: deploy                        # Becomes /deploy. Lowercase, numbers, hyphens only.
description: Deploy the app         # Claude uses this to decide when to auto-invoke
argument-hint: [environment]        # Shown during autocomplete: /deploy [environment]
disable-model-invocation: true      # Only manual /deploy works — Claude won't auto-invoke
user-invocable: false               # Hidden from / menu — background knowledge only
allowed-tools: Read, Grep, Glob     # Tools allowed without permission prompts
model: claude-sonnet-4-6            # Override the model for this skill
context: fork                       # Run in an isolated subagent
agent: Explore                      # Subagent type (with context: fork)
---

Key Fields Explained

disable-model-invocation: true — Use this for skills that have side effects. A deploy skill should only run when you explicitly type /deploy, not when Claude thinks you might want to deploy.

user-invocable: false — Use this for background knowledge. A skill with your project’s API conventions that Claude should always apply, but you’d never invoke directly.

context: fork — Runs the skill in a separate subagent with its own context window. Good for research tasks or anything that would generate a lot of output you don’t want cluttering your main conversation.

allowed-tools — Pre-approves specific tools so Claude doesn’t prompt you for permission every time. A read-only research skill might allow Read, Grep, Glob. A deployment skill might allow Bash.

Practical Skills You Should Create

Code Review

---
name: review
description: Review code for bugs, security issues, and project conventions
allowed-tools: Read, Grep, Glob
---

Review the current changes (git diff) for:

1. **Bugs** — Logic errors, off-by-one mistakes, null/undefined access
2. **Security** — XSS, injection, exposed secrets, missing validation
3. **Performance** — Unnecessary loops, missing indexes, N+1 queries
4. **Conventions** — Does it follow the patterns in the rest of the codebase?

For each issue, reference the specific file and line. Classify as critical, warning, or suggestion.

Fix GitHub Issue

---
name: fix-issue
description: Read a GitHub issue and implement a fix
argument-hint: [issue-number]
disable-model-invocation: true
---

Fix GitHub issue #$ARGUMENTS:

1. Read the issue: `gh issue view $ARGUMENTS`
2. Understand the requirements and acceptance criteria
3. Explore the relevant code
4. Implement the fix
5. Write or update tests
6. Run the test suite to verify
7. Commit with message: "fix: resolve #$ARGUMENTS — [brief description]"

Usage: /fix-issue 423

Create Component

---
name: component
description: Create a new React component with tests
argument-hint: [ComponentName]
disable-model-invocation: true
---

Create a new React component called $ARGUMENTS:

1. Create `src/components/$ARGUMENTS/$ARGUMENTS.tsx`
2. Create `src/components/$ARGUMENTS/$ARGUMENTS.test.tsx`
3. Create `src/components/$ARGUMENTS/index.ts` (barrel export)
4. Follow the patterns in existing components
5. Include TypeScript props interface
6. Include at least 3 test cases

Usage: /component SearchBar

PR Summary

---
name: pr-summary
description: Generate a pull request summary from current changes
context: fork
agent: Explore
---

## Context
- Branch diff: !`git diff main...HEAD`
- Changed files: !`git diff main...HEAD --name-only`
- Commit history: !`git log main..HEAD --oneline`

## Task
Write a pull request description with:
1. A one-line summary of what changed
2. A bullet list of specific changes
3. Testing notes (what was tested, what to verify)
4. Any migration or deployment notes if relevant

Database Migration

---
name: migrate
description: Create a database migration
argument-hint: [description]
disable-model-invocation: true
---

Create a new database migration for: $ARGUMENTS

1. Look at existing migrations for naming conventions and patterns
2. Create the migration file with proper timestamp prefix
3. Write both the up and down migrations
4. Add appropriate indexes
5. Test by running the migration: `npm run migrate`
6. If it fails, fix and retry

Security Audit

---
name: audit
description: Run a security audit on the codebase
context: fork
agent: Explore
allowed-tools: Read, Grep, Glob
---

Perform a security audit:

1. Search for hardcoded secrets (API keys, tokens, passwords)
2. Check for SQL injection vulnerabilities (string concatenation in queries)
3. Check for XSS (unescaped user input in HTML)
4. Verify authentication middleware on protected routes
5. Check dependency vulnerabilities: !`npm audit --json`
6. Review .env handling (never committed, .gitignore includes it)

Report findings organized by severity: critical, high, medium, low.
Start simple

You don’t need 20 skills on day one. Start with the 2-3 workflows you repeat most often — commit, review, and one project-specific task. Add more as you identify patterns in your work.

Supporting Files

Skills can include more than just SKILL.md. The directory can hold templates, reference docs, and scripts:

.claude/skills/blog-post/
├── SKILL.md           # Main instructions
├── template.md        # Blog post template to fill in
├── style-guide.md     # Writing conventions
└── examples/
    └── sample-post.md # Example of a well-written post

Claude reads these files when it needs them during skill execution. Keep SKILL.md concise and put detailed reference material in separate files.

Dynamic Context with Shell Commands

The !`command` syntax runs a shell command during preprocessing, injecting its output into the skill before Claude processes it:

---
name: standup
description: Generate a daily standup update
context: fork
---

## What I did yesterday
!`git log --since="yesterday" --oneline --author="$(git config user.name)"`

## Current branch status
!`git status --short`

## Open PRs
!`gh pr list --author=@me`

Based on this context, write a concise daily standup update.

This gives Claude real-time information from your environment without you having to gather it manually.

String Substitutions

Skills support argument substitution:

  • $ARGUMENTS — All arguments as a single string
  • $0, $1, $2 — Individual arguments by position

Example skill for migrating components between frameworks:

---
name: migrate-component
argument-hint: [component] [from-framework] [to-framework]
---

Migrate the `$0` component from $1 to $2.
Preserve all functionality and props. Update imports and syntax.

Usage: /migrate-component SearchBar React Vue

Skills vs CLAUDE.md

Both configure Claude’s behavior, but they serve different purposes:

CLAUDE.mdSkills
LoadedAutomatically, every sessionOn invocation or description match
PurposeProject context, conventions, rulesTask automation, workflows
ScopeAlways activeOn-demand
ComposabilitySingle fileDirectory with supporting files

Put in CLAUDE.md: Coding standards, test conventions, project structure, architectural rules, key commands.

Put in Skills: Repeatable workflows (commit, deploy, review), task templates (create component, fix issue), research tasks (audit, explore).

They work together. When a skill runs with context: fork, the subagent also loads CLAUDE.md, so your project conventions are always available.

Tips for Writing Better Skills

Keep SKILL.md under 500 lines. Move detailed reference material to separate files.

Use numbered steps for workflows. Claude follows sequential instructions more reliably than prose descriptions.

Write descriptions in third person. “Deploys the application to production” works better for auto-invocation than “I can help you deploy.”

Test with different models. A skill optimized for Opus might need more detail if you switch to Sonnet or Haiku.

Use disable-model-invocation: true for anything destructive. Deploys, deletes, commits, and anything that touches production should only run when you explicitly ask.

Include validation steps. “Run the test suite and fix any failures before committing” is better than “commit the changes.”

Don’t over-explain. Claude already knows how to write code, use git, and call APIs. Your skill should describe what to do, not how programming works. Focus on project-specific requirements and decisions.

Sharing Skills With Your Team

Project-level skills (.claude/skills/) are just files in your repo. Commit them and your entire team gets the same workflows:

.claude/
├── CLAUDE.md          # Project conventions
└── skills/
    ├── commit/SKILL.md
    ├── review/SKILL.md
    ├── deploy/SKILL.md
    └── fix-issue/SKILL.md

This is one of the strongest arguments for skills over ad-hoc prompting. When everyone on the team uses the same /commit and /review skills, you get consistency that individual prompting can’t match.