Chapter 4

How to Create a Claude Code Skill: Turn a Repeated Task into One Command

2026-08-22 · 12 min read · 10 XP
Chapter 4 · Make Claude Code Yours: Skills, Subagents, Automation

Claude Code has skills: a way to register a repeated procedure behind a single command. If CLAUDE.md is the rule Claude follows every session without exception, a skill is the procedure you call up only when you need it.

Pasting the same procedure into the chat box a third time is the signal.

Last lesson had you install and run someone else's plugin. Today it's not someone else's work, it's your own procedure, turned into a skill. Just here for skill-writing syntax? This lesson alone covers it. The SKILL.md file format itself doesn't change much, but related options and commands can grow release to release, so cross-check the official docs if you're reading this well after today.

Skill

A skill is a single SKILL.md file that extends what Claude Code can do. Its folder name becomes a slash command you can call directly with /skill-name, and Claude can also find and use it on its own when the conversation calls for it. If you keep pasting the same instruction into the chat box, or a single CLAUDE.md item has swelled into a whole procedure, it's time to move it into a skill.

A skill's structure: one SKILL.md file

A skill is a folder with SKILL.md as its entry point. The simplest form looks like this.

~/.claude/skills/summarize-changes/
└── SKILL.md

YAML frontmatter sits at the top of the file, and instructions Claude follows when it runs come after. Here are the frontmatter fields that actually get used in practice.

FieldRole
descriptionWhat this skill does. Since it's what Claude uses to judge when to call it on its own, this is effectively required
disable-model-invocationIf true, Claude can't call it on its own; only a person can, with /skill-name. Use it for work like deploys or commits where a human needs to control the timing
user-invocableIf false, the reverse: a person can't call it from the menu, and only Claude can use it as reference knowledge
allowed-toolsPre-authorizes tools this skill can use without an approval prompt while it's active
argument-hintThe argument hint autocomplete shows when you type /skill-name, e.g. [Month Year]

Inside the instruction body, you can use a placeholder called $ARGUMENTS. Whatever text you type after the skill name fills that spot exactly. If you need more than one argument, you can split them out in order too, $ARGUMENTS[0], $ARGUMENTS[1].

Where you put a skill decides who can use it. It follows the same shape as the CLAUDE.md location rules.

LocationPathWho it applies to
Personal~/.claude/skills/<name>/SKILL.mdEvery project on your machine
Project.claude/skills/<name>/SKILL.mdJust this project, shared via version control
Plugin<plugin>/skills/<name>/SKILL.mdWherever that plugin is enabled

If a skill with the same name exists in more than one location, the personal one overrides the project one. A plugin's skill gets a plugin-name:skill-name prefix, so it never collides with anything else.

Being able to bundle supporting files alongside it is where a skill parts ways with a custom command. This blog's own post-writer skill is a real example.

.claude/skills/post-writer/
├── SKILL.md         # Skeleton and workflow
├── lexicon.md        # Style vocabulary
└── style-guide.md    # Style rules

SKILL.md holds just the skeleton, and the detailed rules sit in files alongside it, opened only when needed. Worth a side note: this repo's skills also carry scope and execution fields in their frontmatter, which aren't part of the official spec. They're this repo's own convention for marking whether a procedure can be ported as-is to a different agent. A skill runs fine with fields the official spec doesn't define, since it's just YAML.

Turning your own procedure into a skill

Let's put this into practice with the running example this track has followed, the monthly client content report. The CLAUDE.md lesson pinned the report's table format and notation rules into a file. This time, we turn the actual work of pulling a draft together, on top of those rules, into one skill.

In the project you do report work in, create .claude/skills/monthly-report-draft/SKILL.md. If it's a repo you share with a team, this is the right location, since whatever's committed to version control applies to your collaborators too.

---
description: Drafts the monthly client content report. Use it when asked to pull together this month's posts and the change from last month.
argument-hint: "[Month Year]"
disable-model-invocation: true
---
 
# Monthly Content Report Draft
 
Draft the $ARGUMENTS report. Follow this project's CLAUDE.md for format and notation.
 
1. Check the post list and per-channel metrics for this month and last month
2. Build the table per CLAUDE.md's format (first column publish date, second column channel name)
3. Any sentence comparing to last month must cite the number it's based on, in parentheses
4. Add one line suggesting next month's direction at the end of the draft

There's a reason disable-model-invocation: true is set. Drafting the report is work a person decides to start, at a time they pick, not something Claude should run just because the conversation happens to touch on it. The official docs recommend this option for exactly that kind of work: deploys, commits, anything where a human needs to hold the timing.

If this skill always reads the same file or pulls data the same way, adding allowed-tools is worth considering too. If report material only ever comes from one folder in the project, you could set something like allowed-tools: Read(./reports/*) so it stops asking for approval inside that folder. It only applies while this skill is active; every other tool still follows your regular permission settings.

Save it, and typing /monthly-report-draft August fills the $ARGUMENTS spot with "August" before handing it to Claude.

The slash menu showing the freshly created monthly-report-draft skill with its description (captured August 24, 2026)
The slash menu showing the freshly created monthly-report-draft skill with its description (captured August 24, 2026)

Type just /mo and the skill you made shows up in the menu, alongside the description sentence from its frontmatter.

CheckpointBuild .claude/skills/monthly-report-draft/SKILL.md exactly as above and save it. In a Claude Code session, type / alone to open the skill menu and check that monthly-report-draft shows up in the list. Then actually run /monthly-report-draft August and check that the draft follows CLAUDE.md's table format. Both of those confirm this lesson's deliverable is done.

If it doesn't show up in the menu, nine times out of ten the frontmatter's YAML is malformed. Broken indentation or a missing space after a colon inside the --- block means Claude Code reads the body but treats the frontmatter as empty, so calling /monthly-report-draft directly still works while the description just never shows up in the skill menu. If that happens, reopen with claude --debug and check the parse error in the log.

Skills that run smoothly, and skills that don't

Turning something into a skill doesn't automatically make it stable. This blog's own repo has several skills with pretty different personalities, and lining them up side by side makes the pattern visible.

The thumbnail skill has a fully fixed order: draw the pixel grid, run the render command, check that the resulting PNG exists. It runs the same sequence every time, and whether it's done or not can be checked just by whether the file exists. There's almost no room for judgment to creep in, which makes it a great fit for a skill.

factcheck is different. It decides it's done using a condition: "repeat until a round comes back with zero fixes." That judgment call itself is the hard part. What counts as a "fix," and when to run another round, has to be reassessed every time. It stays stable anyway, because the point requiring judgment isn't left vague; it's pinned down with an explicit stopping condition, a round with zero fixes. draft-weave works the same way. It nails down a boundary of what not to do, something like "AI stitches things together; it doesn't rewrite."

Here's the rule that falls out of that. A mechanical task with a fixed order runs fine as a skill, as-is. A task that needs judgment has to nail down, in writing, when it's done and what it should never do, or it runs differently every time. Write "use your judgment and handle it" with no more than that, and a skill with no judgment criteria gives you a different result every run. The post-writer skill layers both: inside its own procedure, it calls the factcheck skill again as one of its steps, which means a skill can reference another skill as a stage in its own process.

Length is worth tracking too. The official docs recommend keeping SKILL.md under 500 lines, since the body loads into context in full every time it's called. In practice, this repo's skills stay well inside that: factcheck and draft-weave run 71 lines each, thumbnail runs 110, and even the longest, post-writer, tops out at 202. That's because the detailed rules live in supporting files next to it, not in the body itself.

How is this different from a custom command?

Autocomplete also carries "claude code custom command" as a top query. There's a reason the official docs cover both on the same page: they're essentially the same mechanism.

This repo actually has both kinds side by side. .claude/commands/handoff.md is a command built the older way, one file with no folder.

---
description: Check and process the worktree handoff inbox
argument-hint: "[pull | new <recipient> <topic>]"
---
 
Check and process worktree handoffs. ...

This file creates a /handoff command, and it works exactly like .claude/skills/post-writer/, a folder-based skill, creates /post-writer. The frontmatter uses the same fields too, description, argument-hint. The official docs state plainly that these are the same mechanism.

The only difference is folder versus single file. A skill is a folder, so it can carry supporting files, lexicon.md, a script, alongside SKILL.md. A command is a single file, so there's nowhere for that to go. For a short procedure with no supporting files needed, a single file in .claude/commands/ is plenty, and existing .claude/commands/ files keep working exactly as before. Still, the official docs recommend the skill folder format for anything new, since you won't have to restructure it later if you end up needing reference material or a script.

The first thing I ever turned into a skill was GA4 data analysis. I kept walking the same sequence out loud in conversation, over and over, until the moment finally hit me: this needs to be bundled. From there I built out routes that ran the same steps on their own for things like checking ad performance, or turning analysis results into a plain-language report, work that used to mean starting the conversation from scratch every time. On the content marketing side I did the same thing, bundling everything from finding a topic to structuring a piece to writing the draft into one chain. The common thread was always the same. The order was already fixed. I was just the one re-saying it out loud, every single time.

In 30 seconds
  • A skill is a folder with SKILL.md as its entry point. description is effectively required, and disable-model-invocation restricts it to human-only calls
  • Being a folder means you can keep reference material or scripts right alongside SKILL.md
  • A mechanical task with a fixed order runs fine as a skill, as-is. A task needing judgment stays stable only if you nail down, in writing, when it's done and what it should never do
  • Keep SKILL.md under 500 lines; the body becomes a context cost every time it's called
  • Custom commands and skills are the same mechanism. The only difference is folder versus single file, and new ones are recommended as folders

Frequently asked questions

How do I create a Claude Code skill?

Create a folder under ~/.claude/skills/ (personal) or .claude/skills/ (project), and write a SKILL.md file inside it. The folder name becomes the slash command, callable as /folder-name. Just having a description in the frontmatter is enough for Claude to judge when to use it automatically, too.

What's the difference between a skill and a custom command?

They're essentially the same mechanism. A .claude/commands/deploy.md file and a skill built as .claude/skills/deploy/SKILL.md both create a /deploy command and work identically. The only difference is folder versus single file. Being a folder means a skill can carry supporting docs or scripts alongside SKILL.md; a command, being one file, can't.

How many lines should SKILL.md be?

The official recommendation is 500 lines or fewer. When a skill gets called, its full body loads straight into the conversation's context, so a longer file costs more every time. Move detailed reference material or examples into a different file in the same folder instead of the SKILL.md body, and reference it only when needed.

How do I stop Claude from calling a skill on its own?

Add disable-model-invocation: true to the frontmatter. That way it only runs when you call it directly with /skill-name, and Claude won't run it automatically just because the conversation touches on it. Use it for work where a human needs to control the timing: deploys, commits, sending messages.

How do I reuse an existing skill in a different project?

Put the skill in your personal location, ~/.claude/skills/, and it's available across every project on your machine. To share it with a whole team and reuse it across multiple projects, bundling it into a plugin and distributing it through a marketplace is the better route.

Does editing a skill take effect right away?

Yes. Edit the SKILL.md text and it applies inside the same session immediately, no restart needed. If you create a brand-new skill directory after the session has already started, though, you'll need to restart Claude Code so it picks up that top-level folder as something to watch.

Sources (2)Expand to see all sources
quest_log.txt
Earned
Chapter 4 complete
+10 XP (total 0)
Skills run smoothly in fixed-order slots; anywhere judgment is involved needs a stopping condition
0/7 · 0%
Lv.1 Novice
0 / 100 XP
100 XP to next level
Next questClaude Code Subagents: Delegating Work to Its Own Context
4 / 7Claude Code Subagents: Delegating Work to Its Own Context< BackNext>