The AI Builder's Guide to Building Skills for Claude Code
By Izzy Aly, Co-Founder, Systems and Architecture
Claude Code didn't just enter the AI coding market; it took it over. Over $2.5 billion in run-rate revenue in under a year (Anthropic, February 2026). Around 39% of professional developers used it at work in May–July 2026, up from 18% in January (JetBrains, August 2026). SemiAnalysis estimates that 4% of all public GitHub commits were authored by it (Gigazine, February 2026). And the thing that makes Claude Code more than a smart autocomplete? Skills.
Skills are how you teach Claude your workflow, your conventions, your judgement. They're markdown files that turn a general-purpose AI into a specialised teammate. And because SKILL.md is now an open standard, supported by dozens of agent products from GitHub Copilot to Gemini CLI to Cursor, a skill you write today runs across the AI tooling ecosystem.
Most guides show you the syntax and stop there. This one covers what actually matters: how Claude reads your instructions, where skills break, how to secure them, and how to compose them into systems.
Key takeaways
- Claude Code passed $2.5 billion in run-rate revenue (Anthropic, February 2026), with 91% user satisfaction (JetBrains, January 2026)
- SKILL.md is an open standard listed as supported by 46 agent products: write once, and your skill runs on Copilot, Gemini CLI, Cursor, and others
- 36.82% of the skills Snyk scanned contain at least one security flaw (Snyk ToxicSkills, 2026): read third-party skills before you install them
- Good skills use progressive disclosure: metadata at startup, full content on activation, references and scripts only when needed
Why Build Skills for Claude Code?
The AI code assistants market was estimated at $8.14 billion in 2025 and is projected to reach $127.05 billion by 2032 (MarketsandMarkets).
Claude Code isn't just participating. In February 2026 its run-rate passed Cursor's, which had just topped $2 billion (Bloomberg, March 2026). And it didn't win on features: Copilot shipped years earlier; Cursor built a whole IDE. Claude Code won on customisability. Skills are the mechanism.
Here's the part most tutorials miss: SKILL.md isn't a Claude Code proprietary format. It's an open standard. Anthropic developed the format and released it as an open specification, and the spec's client showcase now lists 46 agent products that support it, including GitHub Copilot, OpenAI Codex, Google Gemini CLI and Cursor (Agent Skills, October 2026). Anthropic's public skills repository on GitHub has more than 180,000 stars (GitHub, October 2026). You're not writing a Claude Code plugin. You're writing a portable AI capability.
So why does this matter for you as a builder? Because the skills ecosystem is exploding, and most of it is mediocre. The gap between a prompt someone tossed into a file and a well-architected skill is the gap between a tool that frustrates and a tool that feels like it reads your mind. This guide is about closing that gap.
In its January 2026 AI Pulse survey of 10,000+ developers, JetBrains found Claude Code at 18% workplace adoption with the highest loyalty scores on the market: 91% customer satisfaction and an NPS of 54 (JetBrains Research, April 2026). Skills are the customisation layer that turns high satisfaction into deep integration with how your team actually works.
The Anatomy of a SKILL.md File
Every skill starts as a single markdown file with YAML frontmatter, in a folder named after the skill. Claude Code reads the frontmatter at session startup (the name and description determine when your skill activates) and loads the full body and any referenced files only when the skill matches the current task.
Here's the minimal skeleton:
---
name: commit-writer
description: Write conventional commit messages from staged diffs
allowed-tools: [Bash(git diff *), Read]
---The frontmatter fields break down like this:
name. A short, filesystem-safe identifier: lowercase letters, numbers and hyphens, up to 64 characters. The spec requires it to match the skill's folder name (Claude Code falls back to the folder name if you leave it out), and it becomes the slash command you can type (/commit-writer). Don't overthink it; code-reviewer beats comprehensive-typescript-code-quality-assessment-tool.
description. This is the most important field you'll write. Claude uses it to decide whether to load your skill for a given task. It needs to describe when the skill applies, not just what it contains. "Use when reviewing pull requests for security vulnerabilities and code quality" is specific and triggerable. "A skill that helps with code" is neither. The spec caps it at 1,024 characters.
context and agent. Leave both out for a normal skill. Setting context: fork runs the skill in a subagent, and agent picks which subagent type. That's an advanced pattern we'll cover later.
allowed-tools. The tools Claude can use without asking your permission during the turn that invokes the skill. It pre-approves; it doesn't fence: every other tool stays callable under your normal permission rules. If your skill only reads files and writes commits, don't pre-approve destructive shell access.
model (optional). Pin a specific model if your skill needs particular capabilities. Use Sonnet for fast iteration skills, Opus for architecture-level work. Don't override unless you have a reason.
Descriptions that name specific triggers ("when reviewing PRs", "before committing") activate far more reliably than generic ones. Claude matches your request against the description to decide whether a skill applies, so treat your description like search engine optimisation for an audience of one very literal reader.
Progressive Disclosure: How Claude Reads Skills
Claude Code doesn't load your entire skill folder into memory at startup. It uses a three-tier progressive disclosure system, and understanding these tiers is the difference between a skill that gets used and one that gets ignored.
Tier 1: Metadata at session start. Claude loads the name and description from every skill it can find: your project's .claude/skills/, your personal ~/.claude/skills/, and any plugins. That's it. The Agent Skills spec budgets roughly 100 tokens per skill for this. If your description doesn't match the task, Claude never reads another word of your skill file.
Tier 2: Full markdown on activation. When Claude determines a skill matches the current task, it loads the entire SKILL.md body: instructions, examples, rules, decision frameworks. This is your main canvas. Every word here costs context budget, and Claude's context window is finite. The spec recommends keeping the body under 5,000 tokens and SKILL.md under 500 lines (Agent Skills specification). Past that, the skill starts competing with the user's actual code for attention.
Tier 3: References and scripts on demand. Files in a references/ or scripts/ subdirectory within your skill folder only load when Claude explicitly reads them via a tool call. Scripts run through bash, and only their output enters context. Put reference material, long examples, and executable scripts here, not in the main SKILL.md body.
This structure exists because context is the scarcest resource in AI-assisted development. Claude Code juggles your codebase, conversation history, system instructions, and skill content in a single context window. A bloated skill body doesn't just waste tokens; it pushes out the code Claude is supposed to be working on.
The rule of thumb: everything in Tier 2 should be instruction. Everything in Tier 3 should be reference. If you find yourself pasting a 200-line code example into your SKILL.md body, move it to references/examples.md and add a note: "See references/examples.md for the full implementation."
The SKILL.md standard's three-tier loading model mirrors how the best agent platforms handle instruction density: compact at invocation, detailed on activation, expansive on demand. When you structure a skill this way, it activates faster, uses less context, and leaves more room for the work that actually matters.
Where Skills Live: The Directory Structure
Skills live in a skills/ directory, one folder per skill, and where that directory sits determines who can use the skill:
.claude/
└── skills/
├── code-reviewer/
│ └── SKILL.md
└── commit-writer/
├── references/
│ └── examples.md
├── scripts/
│ └── format-commit.sh
└── SKILL.md
Project-level skills (.claude/skills/ in your repo) are shared with everyone who clones the project. Use these for team conventions, project-specific workflows, and domain rules. When a new developer clones the repo, they get your skills automatically.
User-level skills (~/.claude/skills/) are personal. They follow you across projects. Use them for your individual preferences: how you like commit messages formatted, your preferred testing workflow, your personal code style rules.
Plugin skills come from installed plugins and are namespaced as /plugin-name:skill-name. You don't edit them in place, but understanding their structure helps you debug conflicts.
The decision framework is simple: if the rule should apply to everyone working on this codebase, put it in project-level. If it's your personal taste, keep it in user-level. Skills with different names in both locations load side by side, so don't create two skills with the same trigger condition unless you enjoy debugging phantom behaviour. Two skills with the same name don't both load: enterprise beats personal, and personal beats project (Claude Code docs).
Writing Your First Skill: A Step-by-Step Walkthrough
Let's build something real: a commit message writer that follows the conventional commits spec. Not because the world needs another commit writer skill, but because it's the right size to demonstrate every concept that matters.
I've built skills for my own workflow, and the pattern I keep re-learning is this: start with the trigger, then write the behaviour, then add the guardrails. Every time I started with the guardrails first, I over-engineered a skill that never activated reliably.
Step 1: Name the skill and write the description
---
name: commit-writer
description: Use when the user asks to write a commit message, generate a commit, or format staged changes into a conventional commit. Reads git diff --staged, writes a commit message following conventional commits (feat, fix, refactor, etc.).
allowed-tools: [Bash(git diff *), Read]
---Notice the description names specific trigger phrases: "write a commit message", "generate a commit", "format staged changes." This is intentional. Claude matches skills against what the user actually types.
Step 2: Write the instruction body
Keep it under 300 words. State the goal, the steps, and the rules:
## Instructions
1. Run git diff --staged to read what's staged.
2. Determine the type: feat, fix, refactor, docs, test, chore, or ci.
3. Identify the scope from the changed files (one word, lowercase).
4. Write the subject line: "type(scope): imperative-mood description" under 72 chars.
5. Write the body: one paragraph explaining WHY, not what. What is in the diff.
6. Output the full commit message. Do NOT run git commit unless the user asks.
## Rules
- Never include Co-Authored-By unless the user has it in their config.
- If the diff is empty, say so and stop.
- If the diff is over 500 lines, suggest splitting into multiple commits.
Step 3: Test and iterate
Stage a small change, then ask Claude to write a commit message. Watch what happens:
- Does Claude activate the skill? (It should load commit-writer before it reads the diff. If it doesn't, ask "What skills are available?" to check the skill is listed, or type /commit-writer to call it directly.)
- Does it follow the format? (Check the output against conventional commits)
- Does it stop at the right boundary? (It should NOT auto-commit)
If activation fails, your description is wrong: add more trigger phrases. If the output is wrong, your instructions are ambiguous: add specifics. Debug the activation problem first, then the quality problem. A perfectly written skill that never triggers is worse than an imperfect one that runs.
Step 4: Extract to references
Once the instructions feel too long, move examples and edge cases to references/. Your SKILL.md body should be the shortest version that reliably produces correct results. Everything else is reference material.
The iteration loop for every skill I maintain: activate, observe, tighten, repeat. Each pass removes words, not adds them.
Security and Guardrails
Here's the stat that should keep you up at night: a Snyk audit of 3,984 skills from two public marketplaces found that 36.82% contain at least one security flaw (Snyk ToxicSkills, February 2026). In the same month, Koi Security identified 341 malicious skills on the ClawHub marketplace (The Hacker News, February 2026).
Skills run with access to your filesystem, your shell, and your network. A malicious or poorly-written skill can read secrets, modify code, exfiltrate data, or run arbitrary commands. The allowed-tools field isn't documentation, but it isn't a sandbox either. It decides what runs without asking you. To take a tool away entirely, use a deny rule in your settings or the skill's disallowed-tools field.
The allowed-tools list
# Tight: pre-approves only what the skill actually needs
allowed-tools: [Read, Grep, Glob]
# Too broad: every shell command runs without a prompt
allowed-tools: [Bash]
# Dangerous: destructive operations run without a prompt
allowed-tools: [Bash(rm *), Bash(git reset --hard *)]
Start with the narrowest list and expand only when the permission prompts get in the way. A commit-writer skill needs Bash(git diff ) and Read, not Bash(). A code reviewer needs Read, Grep, and Glob; it shouldn't need shell access at all. If it must never get shell access, add disallowed-tools: [Bash].
Source review checklist for third-party skills
Before installing a skill someone else wrote, answer three questions:
- Does the allowed-tools list match what the skill claims to do? If a "syntax highlighter" skill pre-approves Bash, something is wrong.
- Are there hardcoded URLs, IP addresses, or data exfiltration paths in the body or scripts? Grep for curl, wget, http, and anything that looks like a webhook.
- Does the skill reference external scripts or dependencies? Follow every
source,.orimport: skills can execute arbitrary code through script references.
Model overrides deserve a mention too. A skill that pins model: opus for a task Sonnet handles fine is burning money, not adding value. Skills that run frequently (commit hooks, lint checks, quick reviews) should target the fastest model that does the job. Reserve Opus for architecture decisions and complex refactors.
The 36.82% flaw rate isn't a reason to avoid skills. It's a reason to be deliberate about them. A skill you write yourself, with a tight allowed-tools list and instructions you've tested, is safer than copying a Stack Overflow answer into your terminal. And it's definitely safer than asking a general-purpose AI to do the same task with unrestricted tool access every single time.
Multi-Skill Architecture Patterns
Once you've written three or four skills, a new problem emerges: they start stepping on each other. Two skills claim to handle code review. A third triggers on every PR-related task. Your commit-writer activates when someone asks about commit history documentation.
Composition is harder than creation. Here are the patterns that work.
One skill, one trigger condition
The single biggest mistake in skill architecture is the "Swiss Army knife" skill: one SKILL.md that handles code review, commit writing, PR description generation, and release note drafting. It activates constantly, consumes enormous context, and does everything mediocrely.
Instead: one skill per distinct trigger condition. code-reviewer activates on "review this." commit-writer activates on "write a commit." pr-description creates PR descriptions. Each is small, focused, and cheap to load. Claude activates the right one based on the task.
Skill-to-skill handoff
When skills do need to chain, use explicit handoff language:
## Instructions
1. Run git diff --staged to generate the diff.
2. After producing the commit message, suggest the user run the PR description
skill: "Now ask me to create a PR description with the PR description skill."
Don't try to make skills call each other automatically. That path leads to infinite loops and context explosions. A skill should do one thing and suggest the next step; let the user drive the transitions.
Subagent skills
Sometimes a task is complex enough that it needs its own agent. Claude Code supports this through forked skills: context: fork runs the skill in a subagent, and agent picks the type (a built-in such as Explore, or your own from .claude/agents/):
---
name: code-reviewer
description: Use when reviewing pull requests for code quality, security issues, and architectural consistency.
context: fork
agent: Explore
background: false
allowed-tools: [Read, Grep, Glob]
---A forked skill runs as a subagent with its own context window, which means it can handle large reviews without competing for space in the main conversation. The subagent doesn't see your conversation history: the skill body becomes its prompt, so write it as a task, not a set of guidelines. background: false makes Claude wait for the result instead of running it in the background. Use this pattern when a skill needs to process a lot of information independently: code reviews, test generation, migration analysis. Don't use it for quick checks or simple transformations; the subagent spawn overhead isn't worth it.
Architecture rule of thumb
If you can describe a skill's job in one sentence and that sentence doesn't include the word "and," the scope is right. "Writes conventional commit messages from staged diffs" is correct. "Writes commit messages and reviews code and generates PR descriptions and updates changelogs" means you need four skills.
When NOT to Build a Skill
Skills aren't free. Every skill you add takes space in the skill listing Claude reads at startup, consumes context budget, and creates another thing to maintain when your workflow changes. A skill is worth building when the task is repeated, structured, and benefits from consistency.
Here's the decision framework I use.
Build a skill when:
| Signal | Example |
|---|---|
| You've done the same task 3+ times and each time you had to re-explain the rules | "No, use conventional commits with the ticket number" |
| The task has a clear input → output shape that instructions can capture | Diff in, formatted commit message out |
| Getting it wrong has real consequences | Security reviews, database migrations, deployment commands |
| You want the same behaviour across multiple projects | User-level skill |
Skip the skill when:
| Signal | Better tool |
|---|---|
| It's a one-time task or happens once a month | Just tell Claude what you want in the moment |
| It's a standing rule, not a triggered workflow | Put it in CLAUDE.md |
| It's an automated trigger (on save, on push, etc.) | Use hooks (settings.json) |
| You're not sure what good output looks like yet | Do it manually a few times first, then codify |
The 3x rule: don't build a skill for something you've done fewer than three times. You don't know the edge cases yet. You'll build the wrong abstraction, and wrong abstractions are worse than no abstractions because they're actively misleading.
Skills are the middle layer in Claude Code's customisation stack. CLAUDE.md handles ambient context ("we use TypeScript strict mode, we prefer functions over classes"). Hooks handle event-driven automation ("run the linter before every commit"). Skills handle triggered expertise ("when I ask for a code review, here's exactly how to do it"). Pick the right layer and you get reliable behaviour. Pick the wrong one and you get a skill that activates when it shouldn't, or a CLAUDE.md that's too long to be useful.
Frequently Asked Questions
Can I use skills written for other AI tools in Claude Code?
Yes. Since SKILL.md is an open standard, most skills written for GitHub Copilot, Cursor or Gemini CLI work in Claude Code with minimal changes. The primary difference is the allowed-tools field: the spec marks it experimental, and Claude Code uses tool-specific names like Bash, Read, and Grep, while other platforms may name them differently. Check the tool names and adjust. Going the other way, strip Claude Code-only fields such as context and hooks before uploading to claude.ai or the API, which reject them.
How many skills should I have active at once?
There's no hard limit, but context is finite. Every skill's name and description load at startup, and Claude Code budgets the whole listing at 1% of the model's context window. When the listing overflows, it drops descriptions from the skills you invoke least, and a skill without its description can't be matched to your request (Claude Code docs). If you're collecting skills like trading cards, you're doing it wrong.
Do skills work with Claude's API, or only in the CLI?
Both. Claude Code reads skills from the filesystem. The Claude API runs them too: you upload a custom skill through the Skills API (/v1/skills) and reference it in the request's container, alongside the code execution tool (Claude Platform docs). API-uploaded skills stay on the API: upload each one separately there. Claude Code can download the skills you've turned on in claude.ai, but never uploads its own (Claude Code docs).
What's the difference between a skill and a custom slash command?
In Claude Code they've merged. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy, and existing command files keep working. By default every skill can be run by hand as /skill-name, and Claude can also load it on its own when the task matches the description. If you only want the explicit trigger, for a deploy, say, set disable-model-invocation: true.
Do I need to know how to code to build a skill?
No. SKILL.md files are plain markdown with YAML frontmatter. If you can write clear instructions in English, you can build a skill. The advanced patterns (subagent configuration, reference scripts, multi-skill architecture) benefit from engineering experience, but a basic skill that captures your preferences for a repeated task requires nothing more than knowing what you want Claude to do and communicating it clearly.
Conclusion
Skills are the difference between using Claude Code and building on it. A well-crafted skill captures your expertise in a form Claude can apply consistently, across projects, and across the dozens of agent products that now speak SKILL.md.
The patterns that separate good skills from the mediocre ones are straightforward: specific triggers, tight scopes, progressive disclosure, narrow allowed-tools lists, and ruthless editing. A 200-word skill that activates reliably and produces correct output is better than a 2,000-word skill that never loads.
Start with the commit-writer pattern from this guide. Observe how it activates. Tighten the description. Move examples to references. Then build your second skill: something specific to your stack, your conventions, your pain points. By the third one, the patterns will feel obvious.
The AI coding market is consolidating around platforms that support customisation. Skills are the customisation primitive. The builders who invest in them now are the ones whose tools feel like extensions of their brain six months from now.
- Topics
- Share