All articles Day 8 · Extending it

Teach it once.
Reuse it forever.

By Kowshik Kesavarapu 5 min quick start + 18 min full guide Oct 18, 2026

Companion page: after you read this, see how to publish your skill as open source: GitHub repo, license, plugin, marketplace and updates, with create-launcher as the example.

01What a skill is, and why you want one

What. A skill is a folder with one file in it, SKILL.md. The file has two parts: a short header that says what the skill is for, and plain Markdown instructions that say how to do it. Think of it as a written procedure you hand to a new teammate, except the teammate is Claude.

Why. Look at the prompts you type more than once: "review this like we do", "write release notes in our style", "set this project up so I can run it". Each time you retype them you forget a detail, and each teammate words them differently, so results drift. A skill fixes the wording once, keeps it in a file you can edit and version, and makes the result repeatable.

How it works. Claude Code puts only the one-line description of every skill in the session. The full instructions load only when the skill is used. That is the key design: you can keep dozens of skills and pay almost nothing in context until one is needed. A skill runs in one of two ways. Claude loads it on its own when your request matches the description, or you call it with /skill-name.

02Skill, CLAUDE.md, prompt or command?

You already know two ways to steer Claude. A skill is the third, and it helps to know which to reach for:

CLAUDE.md (Day 2)Facts that are true all the time: your stack, your commands, your conventions. Loaded every session. Keep it short because it always costs context.
A promptOne-off instructions for one conversation. Gone when the chat ends.
A skillA procedure you need sometimes: review a PR, generate scripts, write notes. Costs one line until used, then loads in full.
A custom commandThe older form, one Markdown file in .claude/commands/. Still works and makes the same /name. Skills are the newer form with more features (section 13).

A simple test: if Claude should always know it, put it in CLAUDE.md. If you would only want it when a certain job comes up, make it a skill.

03Where skills live

What. The folder you put a skill in decides who gets it. Why it matters: a personal habit should not clutter your team's repo, and a team standard should not depend on one person's laptop. How: pick the folder that matches who should have it.

Personal~/.claude/skills/<name>/SKILL.md. Every project, only you. On Windows that is $HOME\.claude\skills\. Good for your own habits.
Project.claude/skills/<name>/SKILL.md inside the repo. Commit it and every teammate who clones gets it. Good for team standards.
Nestedpackages/api/.claude/skills/.... Loads when Claude works on files under that folder. Good for monorepos where each area has its own rules.
PluginShipped inside a plugin and used as /plugin-name:skill-name. Plugins get their own day later in the series.
Name clashIf two skills share a name, enterprise beats personal, and personal beats project.

04A real skill: create-launcher

What. create-launcher is a skill I wrote and use. It inspects a project, works out its stack (Python, Node, or a frontend plus backend), and writes three start scripts, launch.sh, launch.bat and launch.ps1, so anyone can run the project on any operating system. It is open source at github.com/Kowshik46/create_launcher_skill.

Why it is a good skill. The job is the same every time but the details are fiddly: which package manager, where the virtual environment lives, how to stop every process on Ctrl+C, how to avoid PowerShell's execution-policy block. Writing that into a prompt each time is error-prone. Written once as a skill, it is correct every time.

How to install it. A skill is just a file, so installing means copying it into a skills folder. From PowerShell:

>_Install a skill
—☐✕
git clone https://github.com/Kowshik46/create_launcher_skill
mkdir .claude\skills\create-launcher
copy create_launcher_skill\.claude\skills\create-launcher\SKILL.md .claude\skills\create-launcher\

# for every project instead, use your home folder
mkdir $HOME\.claude\skills\create-launcher

How to use it. Open Claude Code in a project and either type /create-launcher, or ask in plain words: create launcher scripts for this project. The second works because Claude compares your request with the skill's description. There is no restart: Claude Code watches skill folders. The one exception is a brand-new top-level skills folder created mid-session, where you run /reload-skills.

How it is built. Open its SKILL.md. Every part is doing a job:

>_.claude/skills/create-launcher/SKILL.md (shortened)
—☐✕
---
name: create-launcher
description: Use when the user asks to create a launcher, setup script, or run configuration for a project. Detects the stack, provisions a missing .env, and generates launch.sh, launch.bat and launch.ps1.
---

## Step 1: Detect services
Python: requirements.txt or pyproject.toml. Node: package.json...
## Step 2: Environment files
Copy .env.example to .env only if .env is missing. Never print it.
## Step 3: Rules for all three scripts
Run from the script's own folder. Stop everything on Ctrl+C...
## Step 5: Verify
Run bash -n launch.sh. Do not start the services unless asked.
## Step 6: Report
List files, services found, TODOs, and how to run each script.
A "use when" descriptionIt opens with Use when the user asks for a launcher. That tells Claude exactly when to pick it, and it names the words people really say.
Numbered stepsDetect, provision, generate, verify, report. A fixed order means the same behaviour every run.
Guard rails"Never overwrite .env", "never print it", "do not start the services unless asked". These are the rules you would give a new teammate on day one.
A verify stepThe skill checks its own work before it reports. That is what makes a skill trustworthy instead of just fast.
A report formatIt ends with a fixed summary and a table of how to run each script, so the output is predictable.

It also ships as a Claude Code plugin, which bundles skills for easy sharing: claude plugin marketplace add Kowshik46/create_launcher_skill. Want to publish your own skill as open source? Read the companion page, how to publish and share a skill, which covers the repo, license, plugin, marketplace and updates.

05Write your own, step by step

What and why. Your best first skill is a routine you already repeat. You do not need to invent anything: take the prompt you have typed three times and turn the best version of it into a file. Here is a small one that reviews your uncommitted changes.

How. Create the folder and file from PowerShell, or in VS Code with New Folder and New File in the Explorer:

>_Create it
—☐✕
mkdir .claude\skills\review-changes
code .claude\skills\review-changes\SKILL.md
>_.claude/skills/review-changes/SKILL.md
—☐✕
---
name: review-changes
description: Reviews uncommitted changes and flags risks. Use when the user asks what changed, wants a review, or wants a commit message.
---

## Current changes

!`git diff HEAD`

## Instructions

Summarise the changes above in 3 bullets. Then list risks:
missing error handling, hard-coded values, missing tests.
End with a one-line commit message.

Two details matter. The very first line of the file must be ---, otherwise the header is treated as ordinary text. And !`git diff HEAD` is special: Claude Code runs that command before Claude reads the skill and pastes the real diff in its place (section 10). Run it with /review-changes, then improve the skill by editing the file, not by correcting Claude in chat, so the fix is permanent.

06The description: the line that matters most

What. The description is the only part of a skill Claude sees until it decides to use it. Why it matters: if the description does not match how you actually ask, Claude never loads the skill, however good the instructions are. How to write it: say what the skill does, then say when to use it, in the words people really type, and put the main use first.

WeakHelps with code. Matches everything and nothing, so Claude cannot tell when it applies.
StrongReviews uncommitted changes and flags risks. Use when the user asks what changed, wants a review, or wants a commit message. It names the job and the triggers.
Extra triggersAdd a when_to_use field for more example phrases. It is appended to the description.
LengthThe description and when_to_use are cut at 1,536 characters in the listing, so lead with the key use case.

07The header, field by field

Every field is optional, but knowing them lets you shape how a skill behaves. These are the ones you will actually use:

nameThe /command. Defaults to the folder name.
description, when_to_useWhen Claude should use it (section 06).
argument-hint, argumentsA hint shown in autocomplete such as [issue-number], and names for the inputs (section 09).
disable-model-invocationtrue means only you can run it. For anything with side effects (section 08).
user-invocablefalse hides it from the / menu so only Claude uses it. For background knowledge.
allowed-toolsTools Claude may use without asking while the skill runs (section 11).
pathsGlobs such as src/api/**/*.ts. The skill then loads automatically only when Claude works on matching files.
context, agentcontext: fork runs the skill in a separate subagent (section 12).
model, effortUse a different model or effort level for that skill's turn.
shellbash by default, or powershell for the !`command` lines on Windows.

Typos fail silently. Unknown field names are ignored, and if the YAML cannot be parsed the skill loads with no fields at all. If a skill acts strangely, check the header first.

08Who may trigger it

What. By default both you and Claude can run a skill. Why change that: some skills should never fire by themselves. A deploy skill that Claude decides to run because you said "ship it" in passing is a bad surprise. How: one line in the header.

DefaultYou can run it, Claude can load it. The description is always in context.
disable-model-invocation: trueOnly you. Claude never loads it on its own, and the description is not even in context. Use it for deploys, commits, pushes and messages.
user-invocable: falseOnly Claude. For knowledge like "how our legacy billing module works" that you would never type as a command.

Rule of thumb: if running it twice by accident would hurt, make it disable-model-invocation: true.

09Arguments: make a skill reusable

What. Anything you type after the skill name is passed in as arguments. Why: one skill can then serve many cases, such as any issue number or any component name, instead of you writing a new skill each time. How: use a placeholder in the body.

>_.claude/skills/fix-issue/SKILL.md
—☐✕
---
name: fix-issue
description: Fix a GitHub issue on a branch
disable-model-invocation: true
arguments: [issue, branch]
---

Fix GitHub issue $issue on branch $branch.
Follow our coding standards and write tests.

# run it:
> /fix-issue 123 fix/login-bug
$ARGUMENTSEverything you typed after the name, as one string.
$0, $1 or $ARGUMENTS[1]One argument by position, counting from 0. Quote multi-word values: /skill "hello world" two.
$issue, $branchNamed arguments, filled in the order listed in arguments. Easier to read than numbers.
${CLAUDE_SKILL_DIR}The skill's own folder, so it can point at its own files.
No placeholder?If you pass arguments but the body uses none, Claude Code appends ARGUMENTS: ... so the input is not lost.

10Live context: feed it real data

What. A line written as !`command` runs a shell command first and is replaced by its output. Why: Claude then starts from the real diff, the real PR or the real test output instead of guessing or spending turns running commands. How: put the command in the body where the data belongs. For several lines use a fenced block that opens with ```!.

Know the limits. The command goes through your permission rules like any other. If an injected command fails, the whole skill stops, so use commands you know work in that project. The default shell is bash; add shell: powershell to the header when the command is PowerShell, as on many Windows machines.

11Supporting files and pre-approved tools

What. A skill folder can hold more than SKILL.md. Why: a long skill wastes context every time it loads. Keep SKILL.md short (under 500 lines) and move reference material, examples and scripts next to it. How: mention each file in SKILL.md with a line on when to read it.

>_A skill folder
—☐✕
release-notes\
  SKILL.md         overview: when and how
  style-guide.md    read when writing the notes
  examples.md       good and bad past notes
  scripts\collect.ps1  run, never loaded as text

Claude reads a supporting file only when the task needs it, and runs a script instead of loading it. To let a skill run specific commands without a prompt each time, pre-approve them in the header:

>_header
—☐✕
allowed-tools: Bash(git log *) Bash(git tag *)
# or a bundled script:
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)

This only adds permission, and only for the turn that runs the skill. It clears on your next message and never loosens the Day 5 rules for anything else. Keep the list as narrow as the skill needs.

12Run it in a fork

What. Adding context: fork runs the skill in its own subagent, a separate Claude with a fresh context. Why: jobs that read dozens of files would flood your main conversation. In a fork all that reading happens off to the side, and only the summary comes back, so your main session stays sharp (Day 5). How: two header lines.

>_.claude/skills/deep-research/SKILL.md
—☐✕
---
name: deep-research
description: Research a topic thoroughly across the codebase
context: fork
agent: Explore
---

Research $ARGUMENTS thoroughly:
1. Find relevant files with Glob and Grep
2. Read and analyse the code
3. Summarise findings with file references

agent chooses the kind of subagent. Explore is a read-only searcher, a safe choice for research. This is a first taste of subagents, which are the next topic.

13Custom slash commands: the older way

What. Before skills, a custom command was a single Markdown file in .claude/commands/ (project) or ~/.claude/commands/ (personal). Why you still see them: they keep working, and plenty of repos have them. .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy, and if both exist the skill wins. How to choose: a command file is fine for a quick one-off prompt. Use a skill when you want supporting files, invocation control, paths or automatic loading. Skills can also replace a built-in command of the same name, so check the / menu before reusing a name.

14In VS Code

Skills are plain files, so the terminal and the extension read the same folders. A skill you write in one place appears in the other.

Find themType / in the Claude panel. Project, personal and bundled skills are all listed.
Run onePick it from the menu or type /create-launcher. Arguments go after the name.
Write oneIn the Explorer create .claude/skills/<name>/SKILL.md and save. No restart needed.
Terminal extrasIn the CLI, /skills lists them all, and you can stack up to six at the start of one message, for example /write-tests /fix-issue 123.

15When a skill does not trigger

The usual causes, in the order to check them:

1. The descriptionIs it specific, and does it say when to use it in the words you would type? This is the most common cause.
2. The headerOpening --- on line 1, valid YAML, field names spelled exactly (hyphens included).
3. Is it listed?Run /skills. If it is missing, run /reload-skills, or start with claude --debug and look at the log.
4. A settingThe skillOverrides setting can turn a skill off or restrict it to user-invocable-only.
5. Long sessionsAfter compaction each used skill keeps its first 5,000 tokens. Put the essentials at the top of the file.

16Skills that already ship with it

Claude Code includes bundled skills, which are good working examples. Try /doctor for a setup check-up that asks before changing anything, /code-review for a review, /debug for a stubborn bug and /loop to repeat a prompt on a timer. Others include /batch, /verify, /run and /claude-api. Run one, notice how it behaves, then copy that shape for your own skills.

17Habits that make skills good

One job each"Review a PR" is a skill. "Do all my chores" is not. Small skills trigger accurately and are easy to fix.
Start from a real repeatWait until you have typed the same prompt three times, then write the skill from the best version.
Write for a new teammateGive the steps, an example of good output, and what not to do.
Add a verify stepTell the skill to check its own work, as create-launcher does, before it reports.
Gate side effectsDeploys, pushes and messages get disable-model-invocation: true.
Commit themProject skills are code. Review changes to them in a PR like anything else.
Let Claude draft itAsk: turn what we just did into a skill in .claude/skills, then read and edit the result.

18Try this today

InstallCopy create-launcher into a project and run /create-launcher on something you want to start with one command.
WritePick one routine you repeat weekly and write a project skill with a sharp description and a few steps.
Run it twiceOnce with /name, once by asking in plain words, to prove the description matches.
TightenFix whatever it got wrong in SKILL.md, not in the chat.

Ready to share what you built? See how to publish a skill as open source.

Next up: subagents. How to split a big job across helpers that each work in their own context.

Follow along

A new article lands every day. I post the short version on LinkedIn.