AC
Chapter 04Context Budget Management

Skills: knowledge on demand

What skills are, how to create them. SKILL.md format, frontmatter options.

40 minLesson 2 of 6

CLAUDE.md is loaded every session. That is its strength — Claude always knows your project rules. But it is also its weakness. Everything in CLAUDE.md costs context tokens whether you need it or not.

Skills solve this problem. They are markdown files that Claude loads only when triggered. Zero context cost until you actually need them.

What a skill is

A skill is a .md file in the .claude/skills/ directory. It has YAML frontmatter with a name and description, and a markdown body with instructions. When Claude detects that a skill is relevant — either because you triggered it with a slash command or because the task matches its description — it loads the file into context.

The key difference from CLAUDE.md: skills are on-demand. A deploy checklist that is 800 tokens does not cost you anything during a debugging session. It only loads when you are actually deploying.

.claude/skills/deploy.md
---
name: deploy
description: Pre-deployment checklist and verification
---

## Pre-deploy checklist
1. Run pnpm build — must pass with zero errors
2. Run pnpm lint — no warnings
3. Check for console.log in modified files
4. Verify environment variables are set
5. Run git diff main...HEAD — review all changes
6. Confirm with user before git push

That is a complete skill. When you type /deploy in Claude Code, it loads this file and follows the steps. When you are doing anything else, it costs you nothing.

Types of skills

There are three ways skills get loaded, and each serves a different purpose.

User-invocable

Triggered by slash commands. You type /deploy, /review, /commit, and Claude loads the matching skill. This is the most common and most reliable type — you decide when it fires.

Auto-triggered

Loaded when Claude detects a matching context based on the skill's description. If your skill's description says "React Native navigation patterns" and you ask Claude to add a new screen, it might load automatically. The keyword is "might."

Agent skills

Loaded by specific agent definitions. When you define a subagent (covered in Lesson 4), you can attach skills to it. The code-reviewer agent loads the code-review skill. The planner agent loads the architecture skill.

For your first skills, stick with user-invocable. They are predictable. You know exactly when they load and what they cost.

When to create a skill vs put it in CLAUDE.md

This is the question I get asked most often. The rule is simple.

If the knowledge is needed every session, it goes in CLAUDE.md. Project structure, dependency rules, anti-patterns that apply to every task — that is CLAUDE.md territory.

If the knowledge is needed occasionally for specific tasks, it is a skill. Deploy checklist, TDD workflow, database migration procedure, code review guidelines — these are skills.

I made this mistake early on. My CLAUDE.md was 200 lines long because I crammed everything into it — deployment procedures, testing patterns, design system conventions, API documentation. The file was so long that Claude would sometimes miss the important rules buried in the noise.

When I moved 60% of that content into skills, two things happened: my CLAUDE.md became sharp and focused, and Claude followed the remaining rules more reliably.

Skills fire 50-80% of the time

This is the critical thing to understand about auto-triggered skills. Unlike hooks (which we cover in Chapter 5), skills depend on Claude's judgment about when they are relevant.

When you explicitly type /deploy, the skill loads 100% of the time. But if you are relying on auto-triggering — hoping Claude will load the right skill based on task context — you are looking at a 50-80% hit rate.

This is not a flaw. It is a design choice. Skills are suggestions. They encode best practices and workflows. If Claude does not load a skill when it should have, the outcome is suboptimal but not catastrophic. If a critical enforcement does not fire, that is catastrophic. Different mechanisms for different reliability requirements.

Anatomy of a good skill

A good skill has three properties: it is actionable, it is scoped, and it is self-contained.

Actionable means it tells Claude what to do, not just what to know. "Our API uses REST conventions" is reference information. "When creating a new API endpoint: 1) create the route file, 2) add Zod validation, 3) update the router, 4) add a test" is actionable.

Scoped means it covers one workflow or one domain. A skill that covers "everything about testing" is too broad. A skill that covers "how to write integration tests for TRPC routers" is scoped.

Self-contained means Claude does not need to load other files to follow the skill. Include the patterns, the file paths, the commands. Do not say "refer to the testing guide" — inline the relevant parts.

.claude/skills/trpc-test.md
---
name: trpc-test
description: Write integration tests for TRPC routers
---

## TRPC integration test pattern

### File location
Tests go in __tests__/ next to the router file.
Example: packages/api/src/routers/__tests__/leads.test.ts

### Template
1. Import the router and create a test caller
2. Mock Supabase client with vi.mock
3. Test each procedure: valid input, invalid input, error cases
4. Assert both the return value and any side effects (DB calls)

### Commands
- Run single test: pnpm vitest run packages/api/src/routers/__tests__/leads.test.ts
- Run all API tests: pnpm vitest run packages/api/
- Watch mode: pnpm vitest packages/api/

### Common mistakes
- Forgetting to mock the auth context for protected procedures
- Testing the HTTP layer instead of the procedure directly
- Not testing error cases (invalid input, missing auth)

Notice how everything Claude needs is right there. File paths, template structure, commands, common mistakes. Claude can follow this skill without reading any other files.

Trigger-table lazy loading

This is an advanced pattern I use for projects with many skills. Instead of loading full skills on every match, you create a lightweight index skill that maps keywords to sub-skills.

The index skill itself is small — maybe 300 tokens. It contains a table of keywords and corresponding skill files. When a keyword matches, Claude loads just the relevant sub-skill instead of the full library.

.claude/skills/index.md
---
name: project-guide
description: Routes to the right workflow skill based on task type
---

## Skill routing table

| Keyword | Skill file | When to load |
|---------|-----------|-------------|
| deploy, release, push | .claude/skills/deploy.md | Deploying to production |
| test, spec, coverage | .claude/skills/trpc-test.md | Writing or running tests |
| migrate, schema, table | .claude/skills/migration.md | Database changes |
| component, ui, design | .claude/skills/component.md | New UI components |
| review, pr, diff | .claude/skills/review.md | Code review |

Load ONLY the matching skill file. Do not load all skills.

Without this pattern, Claude might load 3-4 skills at once when the task touches multiple areas. With the index, it loads one skill at a time — the most relevant one. This reduces baseline context by 50% or more in skill-heavy projects.

Building your skill library

Start with one skill. The one workflow you repeat most often. For me, it was deployment — I had a mental checklist I ran every time, and I kept forgetting steps. Turning it into a skill meant Claude would never forget.

From there, add skills when you notice patterns:

  • You explain the same thing to Claude in multiple sessions? That is a skill.
  • You have a multi-step workflow you follow every time? That is a skill.
  • There is domain knowledge Claude needs but only for specific tasks? That is a skill.

Do not create skills preemptively. Wait until you have done the workflow at least twice manually. Then capture it. Skills built from real experience are always better than skills built from imagination.

How far does this go? The most complete open-source skill libraries have 127+ skills, organized by domain: core development (TDD, verification, security), framework-specific (Django, Laravel, Spring Boot, Next.js), language-specific (Python, Go, Rust, Kotlin, Swift), infrastructure (Docker, database migrations, deployment), and even content and business skills. They are not all loaded at once — the domain-based directory structure means Claude finds and loads only the relevant skill for the task at hand.

You will not build 127 skills. But the organizational principle matters: group by domain, not by creation date. When your library grows past 8-10 skills, this structure prevents Claude from loading three skills when it only needs one.