What this covers
A complete walkthrough of Claude Code skills: what they are, how to invoke them, how to write a SKILL.md, when to use hooks or subagents instead, and how to share with a team.
Key tools and concepts:
- Claude Code: Anthropic’s command-line AI coding agent that can read, edit, and run code in your terminal.
- Claude: Anthropic’s conversational AI assistant (similar in role to ChatGPT) with file, long-context, and tool support.
Who this is for
Developers who can run claude and want to turn “the same workflow I keep retyping” into “type /<name> and it runs.” Also for anyone responsible for standardizing code review, security review, or release checks across a team.
When to reach for it
- You’ve executed the same workflow three or more times: security review, pre-release QA, batch metadata edits, test generation.
- The workflow is more than a single prompt — it needs reference docs, template scripts, or a step-by-step checklist.
- The team wants everyone to run the same standard rather than each person writing their own prompt.
- You want Claude to automatically apply a workflow when the context fits, instead of relying on humans to remember.
Skill vs. slash command vs. hook vs. subagent
These four concepts get conflated. Separate them first:
- skill: a documented workflow stored in
SKILL.md. Claude loads it automatically when the task matches the skill’s description; you can also invoke it explicitly with/<name>. Skills can ship with scripts, templates, and references. - slash command: plain-text expansion defined under
.claude/commands/; it injects a template into the prompt. Use it to “reuse a single instruction.” - hook: a shell command triggered on an event (
PreToolUse,PostToolUse,Stop,UserPromptSubmit, etc.). Use it for automated behavior like “run lint after every file write.” - subagent: runs a task in a separate context window and returns the result. Use it for parallel research or to isolate a long context.
Decision shortcut:
| You want… | Use… |
|---|---|
| ”Reuse that one long prompt” | slash command |
| ”Apply a workflow whenever this kind of task shows up” | skill |
| ”Run prettier automatically after edits” | hook |
| ”Investigate five files in parallel and summarize” | subagent |
What’s unique to skills: Claude can auto-select them based on the task — you don’t have to remember to type /.
What a skill looks like
A skill is a directory with at least a SKILL.md, plus any scripts, docs, or templates you need:
.claude/skills/
ship/
SKILL.md
templates/
changelog.md
scripts/
bump-version.sh
SKILL.md describes itself via frontmatter:
---
name: ship
description: |
Ship workflow: detect base branch, run tests, review diff,
bump VERSION, update CHANGELOG, commit, push, create PR.
Use when the user says "ship", "release", or asks to cut a version.
---
# Ship workflow
1. Run `git status` and `git diff` to confirm a clean tree.
2. Run the test suite. If it fails, stop and show the output.
3. ... (steps)
Key points:
descriptionis the index Claude matches tasks against. The more specific (trigger words, typical scenarios), the more accurate auto-selection becomes.- The body is the instruction Claude reads. It can reference sibling scripts and templates via relative paths.
- Don’t load
descriptionwith nouns. “For code review” — too vague. “Pre-landing PR review of the diff against the base branch for SQL safety, LLM trust-boundary violations, and conditional side effects” — precise.
Where skills live
Skills can come from four sources, in priority order:
- Project-level:
.claude/skills/<name>/SKILL.mdlives with the repo; all collaborators get it. - User-level:
~/.claude/skills/<name>/SKILL.mdfollows you across projects. - Plugin: installed via a plugin mechanism; usually shows up with a namespace prefix like
gstack:qa. - Built-in: ships with Claude Code (e.g.
init,review,security-review) — no files to write.
Common built-in and official-plugin skills (versions vary — trust your / menu):
| Skill | What it does |
|---|---|
init | Initialize or update the project CLAUDE.md |
review | Review a PR diff for smells and likely bugs |
security-review | Security review of the current branch |
verify | Run the app and confirm a change actually works |
simplify | Review changed code for duplication and trim it |
run | Launch the project and see the change live |
update-config | Edit .claude/settings.json (permissions, hooks, env) |
loop | Run a command on a recurring interval |
schedule | Create / manage scheduled remote agents |
keybindings-help | Help customize ~/.claude/keybindings.json |
fewer-permission-prompts | Scan history and allowlist common read-only commands |
claude-api | Write Anthropic SDK code and handle version migrations |
Plugin examples (need the corresponding plugin installed):
| Skill | What it does |
|---|---|
gstack:browse | Headless browser for clicking pages, screenshots, before/after diffs |
gstack:qa | Systematic site-wide QA with atomic bug-fix commits |
gstack:ship | One-shot ship: merge base, run tests, update CHANGELOG, push, open PR |
gstack:review | Pre-landing PR review |
gstack:retro | Weekly retrospective over commit history and quality trends |
Not sure what’s available? Type / to see the menu or run /help.
How to invoke a skill
Three ways to trigger:
- Explicit
/<name>: type/in the input, pick the skill from the menu, press Enter. Most direct. - Automatic: when your description of the task matches a skill’s
description, Claude loads it. e.g. “audit the security risks in this PR” might auto-triggersecurity-review. - Explicit by reference: say “use the security-review skill on this branch” in your prompt. More reliable than vaguely asking “check for security issues.”
Skills that take arguments use /<name> <args>:
/loop 5m /verify
/schedule daily 09:00 "summarize yesterday's commits"
Argument format is defined by the skill’s own SKILL.md.
Writing your own skill: a full example
Suppose you want a pr-summary skill that auto-generates a PR description.
Step 1 — create the file at the project root:
.claude/skills/pr-summary/SKILL.md
Step 2 — write the frontmatter and body:
---
name: pr-summary
description: |
Generate a PR description for the current branch.
Pulls commits since the merge-base with main, summarizes
what changed, and produces Summary / Test plan / Risks
sections. Use when the user asks for a "PR description",
"PR body", or is about to open a PR.
---
# Generate a PR description
1. Detect base branch — try `main`, fall back to `master`.
2. List commits with `git log <base>..HEAD --oneline`.
3. Get the diff stat with `git diff <base>..HEAD --stat`.
4. Output three sections:
- **Summary** — 1-3 bullets of what this PR does.
- **Test plan** — checklist of what was verified.
- **Risks** — known unknowns and what to watch in prod.
5. Do not include co-author trailers or auto-generated notes
unless the user asks for them.
Step 3 — run /pr-summary in a session to verify. When the user’s prompt mentions the scenario you described (“draft a PR description”), Claude will also pick it up automatically.
Step 4 — commit the directory. Everyone who pulls the repo gets the skill for free.
Shipping scripts and templates alongside
Skills can reference sibling files:
.claude/skills/release-notes/
SKILL.md
template.md
fetch-issues.sh
Inside SKILL.md:
1. Run `bash .claude/skills/release-notes/fetch-issues.sh <version>`
to collect closed issues since the last tag.
2. Use `.claude/skills/release-notes/template.md` as the output skeleton.
3. Fill in the template. Keep tone matter-of-fact; no marketing language.
Notes: use relative paths, and tell Claude to actually read the template instead of guessing its content — output quality is far more stable that way.
Making auto-trigger actually work
The description field is the entire mechanism for auto-selection. Three rules:
- Include trigger words. What does the user actually say? “ship”, “cut a release”, “review the diff”, “qa” — put those words in.
- Describe when NOT to trigger. e.g. add “Skip if the user only wants to discuss release strategy without actually shipping.”
- State the artifact. “Produces an updated VERSION file, CHANGELOG entry, and a pushed PR” beats “handles releases.”
If your skill never auto-triggers, paste in real phrases you’ve used. If it triggers too often, tighten the scenario description.
Sharing with a team
- Project skills: commit
.claude/skills/to git. Everyone pulls and uses — infrastructure as code. - User-level skills: cross-project but personal. Put them in a private dotfiles repo and symlink into
~/.claude/skills/. - Plugins: list the plugin name and version in your README so teammates can install per official instructions.
You don’t need to run skills in CI, but a lint pass is worth it: check every SKILL.md has both name and description to catch empty-shell directories.
When not to use a skill
- One-off question — a direct prompt is faster.
- Reusing a single sentence — use a slash command (
.claude/commands/<name>.md). - “Run X after every file write” — that’s a hook, not a skill.
- Parallel investigation across contexts — that’s a subagent.
- The description is so vague nobody remembers the skill exists — delete it, rewrite it, or merge it into another.
Drill: do these three things in week one
- Run the existing built-ins:
/init,/review,/security-review— feel how auto-trigger works and what output looks like. - Take a workflow you’ve manually retyped three times and turn it into a project skill. Commit it.
- Have a teammate trigger that skill without you telling them how. If auto-selection misses, rewrite the description.
Quality check
- Does the skill actually auto-trigger? Check the
/menu and the transcript for a “Loaded skill: …” line. - Is output consistent? Two runs should share the same structure and differ only in content.
- Can someone else on the team use it? Have a non-author run it cold.
- Does your
descriptioninclude trigger words, typical scenarios, and the produced artifact? All three.
Common mistakes
- Description like “for code review” — too vague to match.
- Dumping hundreds of lines of steps into
SKILL.md— Claude loses the thread. Number steps and offload detail into referenced scripts. - Hardcoding absolute paths — breaks in another repo. Use relative paths or have the skill probe for what it needs.
- Putting secrets in skill templates — skills go to git, so secrets become plaintext commits. Use env vars or a secret manager.
- Confusing skills with hooks — skills are workflow instructions for the AI; hooks are automated shell commands executed by the harness. Different problems, different tools.
FAQ
Q: What’s the difference between a skill, a hook, and a subagent?
A: A skill is a packaged instruction set the model invokes by name (/skill-name). A hook is a shell command the harness runs at lifecycle events. A subagent is a delegated parallel run. Use skills for repeatable workflows you trigger; hooks for automation that must always run; subagents for parallel research.
Q: How do I make a skill auto-trigger without explicit invocation? A: Add clear trigger phrases in the SKILL.md front matter description. The model matches your message against those triggers — so the description must read like task language, not feature language (“when user asks to review a PR” beats “PR review tool”).
Q: Where should I commit shared skills for my team?
A: In .claude/skills/ at the repo root so they ship with the codebase. Avoid ~/.claude/skills/ for team work — that’s per-user and won’t sync. Never commit secrets to skill templates; use env vars.
Q: Can a skill run shell scripts and templates? A: Yes — package scripts and templates next to the SKILL.md and reference them by relative path. The skill instructions tell the model when to run which file, so keep the directory layout obvious.
Related
Tags: #Claude #Claude Code #Tutorial