
You keep pasting the same procedure into chat. Package it once as a skill, a folder with a SKILL.md, and Claude loads it on demand when the task matches, deep when you need it and nearly free when you don't. We build one from scratch, wire live shell output straight into it, and fix the number one reason a good skill silently never fires.
Episode 5 of Act I. Custom slash commands turned a repeated prompt into one word. Skills are the next rung: a folder of reusable expertise Claude pulls in on its own when the task matches, plus supporting files and scripts that ride along.
The core idea: progressive disclosure. Three loading levels. The name and description are always loaded (~100 tokens each). The SKILL.md body loads only when the skill is triggered. Reference files and scripts load only when referenced, and scripts execute without their code ever entering context. That's why a 2,000-line skill costs almost nothing on the days you don't use it. See Claude Code's skills documentation and the Agent Skills overview.
The copyable workflow. Build a summarize-changes skill: YAML frontmatter with a trigger-shaped description, plus a body that injects live git diff output using the !`command` dynamic-context syntax. Where skills live (personal in ~/.claude/skills/, project in .claude/skills/ committed to git so the team inherits them, plus plugin and managed scope), name-collision precedence, and live reload with no restart. A worked second example: a Postgres migrations skill with a bundled template and a type-generation step.
The knobs that matter. disable-model-invocation and user-invocable to control who triggers a skill, allowed-tools and disallowed-tools tying back to the permissions episode, named arguments, and a peek at context: fork.
When to use what. Facts that are always true go in CLAUDE.md; a prompt you retype becomes a command; a procedure with depth becomes a skill; a task you want quarantined becomes a subagent (coming up next).
The pitfall: the skill that never fires. Almost always a vague description, the only thing Claude sees before invoking. How to diagnose it with "what skills are available?" and /doctor, the description-budget truncation that bites once you have many skills, and the opposite fix when a skill triggers too eagerly. Plus bundled skills, treating untrusted skills like untrusted software, and letting Claude author and refine the skill for you. From Anthropic's skill-authoring best practices.
Here's a moment you've probably already had with Claude Code. You finish some task, a database migration, a tricky refactor, a release checklist, and you realize you just spent five minutes pasting the same block of instructions you pasted last week. The same "here's how we write migrations in this repo, here's the order, here's the thing you always forget." You're hand-feeding the model expertise it should already have. That paste is a signal. It's telling you the knowledge wants to live somewhere reusable.
Last episode we turned a repeated prompt into a custom slash command, one word you type instead of retyping a paragraph. Skills are the next rung up that same ladder. A slash command is a shortcut you trigger. A skill is a shortcut you trigger, plus a body of expertise Claude can reach for on its own when the task matches, plus a folder of supporting files and scripts that come along for free. And the whole thing is built so it costs you almost nothing in context until the moment it's actually needed.
That last part is the real idea, so let's start there before we touch a single file.
The problem skills actually solve
Think about your project memory file, the CLAUDE.md we set up back in episode one. It's always loaded. Every token in it rides along in every single request for the whole session. That's exactly what you want for facts and conventions: your stack, your naming rules, the directories that matter. Short, stable, true everywhere.
But you've probably watched that file grow. Someone adds a forty-line section on how to handle PDF parsing. Someone else adds your entire deploy procedure. Now every conversation about a typo in the footer is dragging your PDF parsing playbook through context, paying for it in tokens and in attention, even though it's irrelevant ninety-nine times out of a hundred. The file turned from a list of facts into a junk drawer of procedures.
Skills fix that by inverting when the knowledge loads. The procedure sits on disk, fully written, as detailed as you like. Claude doesn't read the body until a task actually calls for it. So you can have a two thousand line skill for wrangling Excel files and it costs you essentially nothing on the days you never touch a spreadsheet. That's the unlock. Expertise that's deep when you need it and invisible when you don't.
Progressive disclosure, the three levels
Anthropic calls the mechanism progressive disclosure, and it's worth understanding the three levels because they explain every design choice that follows.
Level one is the metadata, and it's always loaded. Every skill has a little header at the top, and from that header two things get pulled into Claude's system prompt at startup: the skill's name and a one or two sentence description of what it does and when to use it. That's it. Roughly a hundred tokens per skill. This is how Claude knows the skill exists and when it might be relevant, without ever reading the whole thing. If you have thirty skills installed, you're paying thirty short descriptions, not thirty full documents.
Level two is the instructions, the main body of the skill, and it loads only when the skill is triggered. Either you type the slash command for it, or Claude reads that description, decides the current task matches, and pulls the body in. A typical body is under five thousand tokens. This is where your actual procedure lives: the steps, the gotchas, the order of operations.
Level three is everything else in the skill's folder. Reference documents, data files, templates, scripts. These load only if and when Claude reaches for them, and some of them never load into context at all. A script, for instance, gets executed. Claude runs it and sees the output. The hundred lines of Python inside it never enter the conversation. So you can bundle a big validation script or a thick API reference next to your skill, and it sits there at zero cost until the exact moment it's referenced.
Picture a skill for working with PDFs. The metadata, name and description, is loaded from the start. The day you ask Claude to fill out a PDF form, the body loads and walks it through the process. Tucked beside that body are separate files, one on form fields, one a longer reference, plus a couple of scripts. Those stay on disk until the body points Claude at the specific one it needs. You get a deep, capable skill that, on a quiet day, is just a hundred tokens of "I can do PDFs."
Hold onto that three-level picture. Almost every best practice we hit later is really just "respect the levels": keep the description sharp because it's always loaded, keep the body lean because it loads often, push the heavy material into side files because they load rarely.
Building your first skill
Let's make one. The workflow is the same every time, so I'll walk it once slowly.
A skill is a directory with one required file inside it. The file is named SKILL.md, all caps for SKILL, lowercase m d. Where you put that directory decides who can use it, and we'll get to the options, but for your own personal use across every project, it goes in a skills folder inside your home directory's Claude config. So you make a new folder named for the skill, and inside it a SKILL.md.
The file has two parts. Up top, a little block of settings fenced off by three dashes above and below. That's YAML frontmatter, the same format you've seen in static site generators. Below the closing dashes, plain markdown. That markdown is the instructions Claude follows.
Let's build something genuinely useful: a skill that summarizes your uncommitted changes and flags anything risky. In the frontmatter, the one field that matters most is the description. Write it in the third person, and make it say both what the skill does and when to use it. Something like: "Summarizes uncommitted changes and flags anything risky. Use when the user asks what changed, wants a commit message, or asks to review their diff." Notice it's stuffed with the words a person would actually say, "what changed," "commit message," "review my diff." That's deliberate, and it's the single biggest factor in whether the skill ever fires. We'll come back to why.
Then the body. And here's the feature that makes skills feel alive instead of static. You can drop a line into the body that runs a shell command and pastes its output right into the skill before Claude ever reads it. The syntax is an exclamation point and then the command in backticks. So you write a line that runs git diff against HEAD, and by the time Claude sees your skill, that line has been replaced with your actual diff, inlined. The skill isn't telling Claude "go run git diff." The diff is already sitting there in the text.
Anthropic calls this dynamic context injection. The command runs once, at the moment the skill loads, and the output drops in where the line was. For a multi-line setup, say you want the node version and the npm version and a short git status all at once, you can open a fenced block marked with an exclamation point and list the commands. One caveat worth remembering: the substitution happens a single time, and the output isn't re-scanned, so you can't nest one injected command inside another's output. One pass, then done.
So our body, underneath that injected diff, just says: summarize the changes above in a couple of bullet points, then list any risks you notice, missing error handling, hardcoded values, tests that need updating, and if the diff is empty, say so.
That's the whole skill. Two fields of frontmatter, a body with one live command and a paragraph of instruction. Save it, and here's a nice detail: you don't restart anything. Claude Code watches the skill directories and picks up changes within the session. Add a skill, edit a skill, delete one, it takes effect live. This is the tight authoring loop you want, because your first description is usually wrong and you'll tune it three or four times.
To use it, you've got two doors. You type the slash command, slash and the skill's name, and pass arguments after it if it takes any. Or you just talk: make an edit, then ask "what did I change?" and if your description did its job, Claude recognizes the match, loads the skill, and runs it without you naming it. Same skill, two ways in: you drive it explicitly, or Claude reaches for it.
One behavior to know, because it shapes how you should write the body. When a skill loads, its content drops into the conversation as a single message and stays there for the rest of the session. Claude doesn't re-read the file on every later turn. So write the body as standing instructions, the way you'd write a policy that holds for the whole task, not as a one-time "now do this then stop." If your skill says "first, do X," Claude does X once and the instruction is spent. If it says "always validate before writing," that holds. Think durable guidance, not a single command.
Where skills live, and who gets them
You've got a few homes for a skill, and the choice is really about scope.
Personal skills go in that skills folder under your home Claude directory. They follow you across every project on your machine. Your own little toolbelt.
Project skills go in a skills folder inside the project's dot-claude directory, the same dot-claude folder where your settings and commands already live. Here's the payoff: commit that folder to git, and every teammate who clones the repo gets the skill automatically. No install step, no "hey did you set up the thing." The skill ships with the code. For team conventions, this is the move. Your migration procedure, your release checklist, your "how we write tests here" all become skills that travel with the repository.
There's also plugin scope, skills bundled inside a plugin's own skills directory, which is how skills get distributed and shared more broadly, and for organizations on team or enterprise plans, managed skills pushed out across everyone through managed settings.
When two skills share a name across these levels, there's a clear precedence: enterprise wins over personal, and personal wins over project. Plugin skills sidestep collisions entirely by namespacing, the plugin's name, a colon, then the skill name.
One more discovery nicety for the monorepo crowd. Project skills load not just from your starting directory but from every parent up to the repo root, and Claude Code will also find skills in nested dot-claude folders deeper in the tree, on demand, when you're working with files down there. So a package buried in your monorepo can carry its own skills, and they surface when you're actually in that package.
The frontmatter knobs worth knowing
The description is the star, but a handful of other frontmatter fields earn their keep, and they're how you control behavior.
The name field is optional. Leave it off and the skill takes its directory's name. If you set it, the rules are: lowercase letters, numbers, and hyphens, sixty-four characters max, and you can't use the words "anthropic" or "claude" in it.
Then two fields that control who's allowed to invoke the skill, and they're a matched pair. Set disable-model-invocation to true, and Claude can no longer trigger the skill on its own. Only you can, by typing the command. This is exactly what you want for anything with side effects, a deploy skill, a commit skill, something you never want firing automatically because the model thought it matched. The mirror image is user-invocable set to false, which hides the skill from your slash menu so only Claude reaches for it. That one's for background knowledge you want available but never type yourself.
There's a tools angle too, and it ties straight back to our permissions episode. A skill can carry an allowed-tools field that pre-approves specific tools while that skill is active, so a git skill might pre-clear the specific git commands it needs, sparing you the approval prompts mid-task. And there's a disallowed-tools field that goes the other way, pulling tools out of Claude's reach while the skill runs. The permission system you already learned is the fence; the skill just gets to adjust the gate for its own duration.
A couple more. You can set arguments in the frontmatter, naming positional values the skill expects, and then reference them in the body with a dollar sign and the name. So a "migrate this component" skill might declare a component name and a source framework and a target framework, and you invoke it with those three words after the slash command, and they drop into the body where you placed the placeholders. If you don't name them, you can still reach raw arguments by position, dollar sign zero, dollar sign one, and so on, or grab them all at once. There are a few other handy substitutions too, like the current session id and the skill's own directory path, which matters when your body needs to point at a script sitting next to it.
You can also override the model a skill runs on, or the effort level, per skill. And there's a powerful one, context set to fork, which runs the skill in its own isolated context, more like handing it to a subagent. Park that for a second, because it's the natural bridge to a topic we've got coming up.
Supporting files, where skills outgrow commands
Everything so far you could almost do with a custom slash command. Here's where skills pull ahead, and it goes right back to level three of progressive disclosure.
A skill is a folder, so you can put more than SKILL.md in it. Reference documents. Example files. Templates for Claude to fill in. A scripts subfolder with real, runnable code and its dependencies. In your SKILL.md body, you mention these files by relative path, and Claude loads or runs them only when the work calls for it.
This changes what a skill can be. Your main file stays short, a map and a procedure. The thousand lines of detail, the full API reference, the exhaustive list of edge cases, live in side files that cost nothing until needed. And scripts are the sharpest version of this: when an operation is fragile or fiddly, the kind of thing where you'd rather not have the model improvise, you write a deterministic script, and Claude runs it and reads the result. The code never clutters the conversation. You've taken the error-prone part and made it a tool instead of a suggestion.
Let me make that concrete with a stack a lot of you are running. Say it's a Next.js app on Postgres, and your team has a real procedure for database migrations: every migration needs an up and a down, you name files with a timestamp prefix, you never edit a migration that's already shipped, and you always regenerate the types afterward. That's a procedure, not a fact, and it doesn't apply to most of what you do in a day, so it's a textbook skill rather than a line in CLAUDE.md. You make a migrations skill. The body is the checklist: the file naming, the up-and-down rule, the don't-touch-shipped-migrations rule, and a final step that runs the type generation. Beside it, in the folder, you drop a template migration file with the structure already laid out, and maybe a short reference document listing the three or four schema patterns your team has standardized on. The body points at the template by relative path. Now when you ask Claude to add a column, it loads the skill, copies the template, follows your naming, writes both directions, and regenerates the types, the way your most careful teammate would, every time. Commit that skill folder into the repo's dot-claude directory and the whole team inherits the discipline. Nobody has to remember the rules because the rules ship with the code.
That's the shape worth internalizing: the SKILL.md is the judgment and the sequence, the side files are the raw material, and the scripts are the steps too fussy to leave to improvisation.
That suggests a rule of thumb the docs are blunt about: keep your SKILL.md under about five hundred lines. If it's ballooning, that's your cue to lift material out into reference files and point at them. One word of caution from Anthropic's own authoring guidance, though: keep those references shallow, one level deep from your main file. If a reference file points at another reference file that points at a third, Claude may only skim them, and your carefully filed knowledge doesn't get fully read. Map at the top, leaves one hop away, no deep trees.
And a small portability landmine, since these podcasts are about the stuff you'll actually hit: always write your file paths with forward slashes, even if you're on Windows. Backslash paths break on the Unix machines your teammates and your CI are running. Forward slashes everywhere.
So when do I use what?
By now you've got four tools that all look a little alike, so let's draw the lines cleanly, because picking wrong is its own pitfall.
CLAUDE.md is for facts that are true everywhere and that you want loaded always. Your stack, your conventions, the shape of the repo. Stable, short, omnipresent.
A skill is for a procedure, a body of how-to that applies to some tasks and not others, that you want loaded only when it's relevant. Multi-step workflows, specialized knowledge, anything that would bloat CLAUDE.md if it were always on. If you catch yourself writing a procedure into your project memory, that's a skill trying to be born.
A custom slash command, the thing from last episode, is the lightweight cousin. In fact a command and a same-named skill both give you a slash trigger and behave the same way when you type them. The difference is that a skill adds the folder of supporting files, the frontmatter controls over invocation, and that automatic, description-matched loading. Your existing commands keep working, nothing breaks, but skills are the richer pattern when you need more than a saved prompt. Reach for a plain command when all you want is a canned prompt you type; reach for a skill when there's expertise, files, or "Claude should know to do this on its own" involved.
And subagents, which we've got coming up soon, are a different animal again: a whole separate agent instance with its own context and its own tools, for when you want to wall a task off entirely. A skill normally runs right in your current conversation. The exception is that fork option I mentioned, which lets a skill spin up in isolation like a subagent. So the two ideas touch at the edges, but the default skill is lightweight and in-context, while a subagent is heavier and walled off.
The honest one-liner: facts that are always true go in CLAUDE.md, a prompt you retype becomes a command, a procedure with depth becomes a skill, and a task you want quarantined becomes a subagent.
The pitfall: the skill that never fires
Here's the failure you will actually hit, probably on your second or third skill. You write a great skill. Solid body, useful scripts. And Claude just never uses it. You ask the thing it's perfect for, and Claude does the work from scratch, ignoring the skill entirely.
Nine times out of ten, the description is the culprit. Remember level one: the only thing Claude knows about your skill before invoking it is that one or two sentence description. If you wrote something vague, "helps with documents," "processes data," Claude has nothing to match your request against. The fix is to write the description like a trigger. Say what the skill does and, just as important, when to use it, and pack in the actual words and file types a person would mention. Compare "helps with spreadsheets" against "analyzes Excel spreadsheets, creates pivot tables, generates charts. Use when analyzing Excel files, tabular data, or files ending in xlsx." The second one has hooks, "Excel," "pivot table," "xlsx," that a real request will snag on. You've got one description field per skill and it's doing all the discovery work, so spend your effort there.
To diagnose it, just ask Claude directly, "what skills are available?" and see whether yours shows up and how its description reads. If it's there but not firing, rephrase your request to lean on the words in the description, and watch whether it catches. If it catches when you mirror the description but not when you talk naturally, your description's vocabulary is too narrow. Widen it toward how you actually speak.
There's a subtler version of this, too, once you've got a pile of skills. All your skill names always load, but if you've accumulated a lot of them, the descriptions start getting trimmed to fit a character budget, and the ones you invoke least lose their text first. So a rarely used skill can go quiet not because its description is bad but because it got truncated. The tool to see this is slash doctor, which will tell you if your skill listing is overflowing its budget and which skills are affected. There are knobs to raise that budget or to mark low-priority skills as name-only on purpose, but the first move is just to run doctor and see.
And the opposite problem exists, worth thirty seconds. Sometimes a skill triggers too eagerly, jumping in when you didn't want it. The cure is the inverse: make the description more specific so it stops matching loosely, or, if it's a side-effecting skill you only ever want to run by hand, set that disable-model-invocation flag so Claude can't reach for it at all. You'll typically tune in one direction or the other, and live reload means each tweak is a five second loop.
A few things you get for free, and one caution
Claude Code ships with a set of bundled skills you already have. The code review skill that finds bugs and suggests simplifications. A verify skill and a run skill that build and launch your app to confirm a change actually works. A debug skill, a loop skill for running something on a recurring interval, one for working against the Claude API. These aren't rigid scripts; they're prompt-based skills that orchestrate real tools, and they're a great way to read how a well-written skill is structured. Crack one open and look at how its description and body are put together.
On sharing and trust, a real caution. A skill hands Claude new capabilities, instructions plus code that can invoke tools and run commands. That means a skill from an untrusted source is genuinely a security exposure, the same category as installing a random package off the internet. Treat it that way. Only run skills you wrote or that come from a source you trust, and before you adopt one from outside, actually read everything in the folder, the body and every script, looking for anything that doesn't match the stated purpose: surprise network calls, files it has no business touching, data heading somewhere external. Skills that pull content from outside URLs deserve extra suspicion, because fetched text can carry instructions of its own. Audit before you trust, especially anywhere near production or sensitive data.
Let Claude write the skill
I'll leave you with the authoring trick that makes all of this faster, and it's almost too obvious: have Claude write the skill for you.
The loop Anthropic recommends goes like this. Do the task once the hard way, hand-feeding the context like always. When you're done, notice what you kept having to explain, and just ask Claude, "turn what we just did into a skill." It'll draft the SKILL.md. Then your job is editor: trim the explanations it over-wrote, because a fresh model is usually smarter than your instructions assume and you can cut the hand-holding, and ask it to file the heavy reference material into separate documents instead of cramming the main file. Then test it. Better yet, test it in a fresh session that wasn't part of writing it, the way a teammate would meet it cold, and watch where it stumbles. Bring the specifics back, "when it used the skill it forgot to check X," and refine. Observe, refine, test, again.
That observe-and-refine rhythm is the whole game with skills. Your first description won't trigger reliably. Your first body will be too long. And because the tool reloads them live, each fix is seconds away. Start with one skill, the smallest annoyance you keep re-explaining, the thing you pasted twice this week. Extract it, watch it fire on its own, and you've turned a chore you were carrying into expertise the tool just has now.
Next time we hand a whole task off to a separate agent and keep only the answer, which is where that fork option starts to make a lot more sense.