# Claude Code skills, with 28 real examples

> A Claude Code skill is a SKILL.md file that becomes a slash command Claude can also load on its own. How to write one, what to avoid, and 28 real examples.

*Updated 2026-10-04.*

A skill is a folder with a `SKILL.md` file in it. The folder name becomes a slash command. The description tells Claude when to load it without being asked. Write one for any task you have explained to your agent twice.

This page covers the format, the frontmatter that matters, and how skills differ from slash commands and subagents. Then it shows the 28 skills a real generated Next.js repo ships with.

## What is a Claude Code skill?

A Claude Code skill is a markdown file with YAML frontmatter, saved as `.claude/skills/<name>/SKILL.md`. You run it by typing `/<name>`. Claude can also load it on its own when your request matches its description.

A skill can be two things:

- **An action.** A procedure with steps: `/deploy`, `/migrate`, `/test-webhook`.
- **Reference.** Knowledge Claude should use for a while: your API style guide, your schema conventions.

Claude Code skills follow the [Agent Skills](https://agentskills.io) open standard. Claude Code adds its own fields on top, like who can invoke a skill and whether it runs in a subagent.

## Where skills live

| Location | Path | Who gets it |
|---|---|---|
| Project | `.claude/skills/<name>/SKILL.md` | Everyone who clones the repo |
| Personal | `~/.claude/skills/<name>/SKILL.md` | You, in every project |
| Nested | `<subdir>/.claude/skills/<name>/SKILL.md` | Sessions in that folder (monorepos) |
| Plugin | `<plugin>/skills/<name>/SKILL.md` | Anyone with the plugin on |

Commit project skills. They are part of the repo, same as your lint config.

A skill folder can hold more than `SKILL.md`. Put long reference material, examples and scripts next to it and link them from the body. They only load when Claude needs them.

## How skills load (and what they cost)

Skills are cheap until you use them. That is the whole point.

- **At session start**, Claude sees each skill's name and description. Nothing else.
- **When the skill runs**, the full `SKILL.md` body enters the conversation and stays there for later turns.
- **Supporting files** load only when the body points Claude at them.

The description and the optional `when_to_use` field share a cap of 1,536 characters in the skill list. Put the key use case first.

Compare that with `CLAUDE.md`, which loads in full on every request. A 300-line deploy checklist in `CLAUDE.md` costs context on every task. The same checklist as a skill costs one line until you deploy.

## Copy this: a minimal SKILL.md

A generic starter, not from the generator. Save it as `.claude/skills/changelog/SKILL.md`:

```markdown
---
name: changelog
description: Write a CHANGELOG entry for the current branch. Use when the user asks for release notes or a changelog line.
disable-model-invocation: true
allowed-tools: Bash(git log *) Bash(git diff *)
---

Write one entry in CHANGELOG.md for the work on this branch.

1. Run `git log main..HEAD --oneline` and `git diff main...HEAD --stat`.
2. Group the changes under Added, Changed and Fixed. Skip refactors a user cannot see.
3. One line per change. Write it for a user, not a reviewer.
4. Add the entry under `## Unreleased`. Do not touch older entries.
5. Show the entry and stop. Do not commit.
```

Type `/changelog` and it runs. `disable-model-invocation: true` means Claude never fires it on its own. `allowed-tools` lets it run those two git commands without a permission prompt, for that turn only.

## The frontmatter fields that matter

Every field is optional. These are the ones you will actually use.

| Field | What it does |
|---|---|
| `name` | The command name. Defaults to the folder name |
| `description` | What it does and when to use it. Claude routes on this |
| `when_to_use` | Extra trigger text, appended to the description |
| `disable-model-invocation` | `true` means only you can run it, with `/name` |
| `user-invocable` | `false` hides it from the `/` menu. Only Claude can load it |
| `allowed-tools` | Tools it can use without asking, during that turn |
| `argument-hint` | Autocomplete hint, like `[issue-number]` |
| `arguments` | Named arguments you can reference as `$name` |
| `context: fork` | Runs the skill in a subagent instead of your thread |
| `agent` | Which subagent type runs it when forked (`Explore`, `Plan`, `general-purpose`, or your own) |
| `paths` | Globs. Claude only auto-loads it while working on matching files |
| `model` | A model for this skill only |

Arguments land in `$ARGUMENTS`. `/fix-issue 123` with a body that says "Fix issue $ARGUMENTS" gives Claude "Fix issue 123".

## A real example: /verify

This is the `/verify` skill from a generated repo, quoted as the generator writes it. It answers one question: can this checkout actually run?

````markdown
---
description: Prove the repo is actually configured, every required env var present, every configured service reachable, and the guard hooks still blocking what they claim to block.
name: verify
---

Answer one question with evidence: **is this checkout of `my-app` in a
state where it can run?** Not "does the dev server start": that succeeds with
half the services missing and fails two hours later inside a request handler.

Run this after a fresh clone, after adding a battery, after rotating a
credential, before a deploy, and any time a bug report starts with "it works on
my machine".

## 1. Run the check suite

```bash
bun run verify
```

`scripts/verify.ts` runs the checks registered in `src/lib/verify.ts`: the env
check first, then one ping per configured service. Each line is `pass`, `fail`
or `skip`, and the process exits non-zero if anything failed.

Read the three statuses precisely: they mean different things:

- **pass**: the variable is set and the service answered.
- **fail**: the thing is configured but broken. Wrong key, wrong region, the
  database is asleep, the domain is not verified. Always actionable.
- **skip**: the battery is installed but its variables are absent, so the check
  did not run. This is correct on a fresh clone and *wrong* on the day you meant
  to ship that feature. Never read past a `skip` without deciding it is expected.

## 2. Fix failures in dependency order

Do not fix them in the order printed. Fix them in the order the app boots:

1. **environment**: anything else is noise until this passes. The failure names
   the missing keys. Every one of them is documented in `docs/onboard.md` with
   the URL of the page that issues it. Add them to `.env.local` (never to
   `.env`, never to a source file) and re-run.
2. **database**: most other services store something.
3. **auth**: sessions gate the rest of the app.
4. **everything else**: payments, email, storage, analytics, errors, AI.

For each failure, reproduce the smallest thing that fails before changing
anything. A wrong `DATABASE_URL` and an asleep branch database produce the same
red line and have nothing in common.

## 3. Check the variables are where they will be needed

`bun run verify` reads `.env.local`. Production reads Vercel. A repo that
passes locally and fails in production almost always failed this step:

```bash
bunx vercel env ls
```

Compare that list against `REQUIRED_ENV` in `src/lib/env.ts`. Every required key
must exist in **Production**, **Preview** and **Development**: a variable set
only in Preview fails a Production build, not a Production request, so it looks
like a build bug.

Remember `NEXT_PUBLIC_*` values are inlined at build time. Changing one in the
Vercel dashboard does nothing until the next deploy.

## 4. Prove the guards still work

```bash
bun run verify:hooks
```

This attempts each blocked action in a sandbox and confirms it was stopped. It
is the only evidence that the safety layer is real, and it catches the two ways
it silently dies: a `.claude/settings.json` that lost its hook wiring, and a
hook script that no longer parses. Run it after any edit under `.claude/`.

## 5. Then the ordinary gates

```bash
bun run typecheck
bun run lint
bun run test
```

`typecheck` runs `next typegen` first, so it is the only command that validates
`PageProps` / `RouteContext` / `LayoutProps` against your actual routes. A
missing route type here means a real 404 later.

## 6. Report

State the result as a short table (check, status, what you did) and finish
with one of exactly two sentences:

- "`my-app` verifies clean: N checks passed, M skipped (`<names>`, not
  configured yet)."
- "`my-app` does not verify: `<check>` fails because `<cause>`. Fix:
  `<the specific action>`."

Never report "mostly working". If a check is failing and you have decided that
is acceptable for now, say which check, why, and what breaks if it is still
failing next week.

## When a check is missing

If you added a service and `bun run verify` says nothing about it, the check
does not exist. Add it to `src/lib/verify.ts` next to the others: a `name` and a
`run()` that returns `pass`, `fail` or `skip`. Keep it cheap (a `HEAD` request
or a `SELECT 1`, never a write, never a paid API call) because `/api/health`
reuses the same registry on every request.
````

*`.claude/skills/verify/SKILL.md`, as generated.*

What makes it work:

- **The description is a promise.** Env vars present, services reachable, guards still blocking. That line is what Claude routes on.
- **It says when to run it.** Fresh clone, new battery, rotated key, before a deploy.
- **The steps are commands**, not advice. `bun run verify`, then `bun run verify:hooks`.
- **It explains the output.** `pass`, `fail` and `skip` each mean something different, and the skill says what.
- **It ends with a fixed report.** One of two set sentences. "Mostly working" is banned.

## All 28 skills in a generated Next.js repo

The Indie SaaS preset (Better Auth, Neon, Drizzle, Stripe, Resend, PostHog, Sentry, admin panel, MDX blog) ships these:

- `/add-admin-action`: Add an admin action (verify an email, reset a plan, delete an account) as a checked, validated, audited server action with a confirm dialog.
- `/add-admin-page`: Add a page to /admin with the role check, a sidebar entry, loading and empty states, and data read through the admin ports.
- `/add-app-page`: Add a page to the signed-in app (sidebar entry, session check, loading state), or a new tab under /settings.
- `/add-email-template`: Add a React Email template, preview it, wire it into a send, and check it renders and lands in a real inbox.
- `/add-event`: Add a product event end to end, catalogue entry, the question it answers, the capture call on the correct side of the network, and a check that it arrives.
- `/add-mdx-component`: Add a component that posts can use without importing it, registered in src/mdx-components.tsx and styled with design tokens only.
- `/add-oauth-provider`: Turn on Google, GitHub or Microsoft sign-in (env keys only), or add another OAuth provider to the list in src/lib/auth/providers.ts.
- `/add-plan`: Add or change a plan or price on Stripe (monthly, yearly or one-time lifetime). Edit src/lib/pricing.ts, create the Stripe price, wire its env var, and prove checkout and the webhook end to end.
- `/add-table`: Add a table to the Drizzle schema, generate and apply its migration, and wire the typed queries for it.
- `/ask-product`: Answer a question about user behaviour from this repo's event catalogue and the PostHog project, with the caveats that make the number usable.
- `/db-branch`: Create, use, reset and delete Neon database branches, for a feature branch, a preview deploy, a migration rehearsal or a point-in-time investigation.
- `/deploy-to-vercel`: Ship my-app to Vercel, local gates, environment variables per scope, preview verification, promotion and rollback.
- `/edit-pricing`: Add, change or remove a plan or a price (monthly, yearly or one-time lifetime) and wire it to the payment provider.
- `/help`: Explain the agentic system in this repo, rules, skills, agents, hooks, solution docs and the CE loop, and where to go for help beyond it.
- `/landing-copy`: Rewrite the landing page, the metadata and the legal details for the real product from a short brief, by editing src/lib/site.ts only.
- `/migrate-on-neon`: Run a schema migration against Neon safely, on the direct URL, rehearsed on a branch first, with a recovery path when it fails halfway.
- `/migrate`: Generate, review and apply Drizzle migrations safely, including backfills, destructive changes and the deploy step.
- `/new-component`: Add a component to the Daylight kit. Prefer pasting from shadcn/ui, fix the two bridge classes, keep it token-only and verify it in both light and dark.
- `/new-post`: Draft, validate and publish a new MDX post in content/blog, with frontmatter that passes the checker and a slug that will never change.
- `/preview-and-test-email`: Diagnose an email problem, not sending, landing in spam, rendering wrong, in the order that finds the cause fastest.
- `/protect-route`: Put an authentication or role check on a page, a route handler, a server action or a whole route group, at the right layer, without a redirect loop.
- `/qa-feature`: Exercise a feature end to end, happy path, unhappy paths, auth boundaries, refresh and mobile, before anyone calls it done.
- `/scrub-pii`: Audit what this app actually sends to Sentry, extend the scrubbing layer for a new field or shape, and respond when something sensitive has already been sent.
- `/security-audit`: Run the standing security pass through the security-auditor agent, secrets, auth boundaries, injection, dependencies and deploy config, and turn findings into fixes.
- `/test-webhook`: Exercise the Stripe webhook endpoint locally. Forward real events with the CLI, buy a subscription and a one-time price, refund one, assert idempotency, and debug signature failures.
- `/triage-errors`: Work the Sentry issue list, rank by users affected, separate regressions from background noise, find the deploy that caused it, and fix or suppress with a reason.
- `/verify`: Prove the repo is actually configured, every required env var present, every configured service reachable, and the guard hooks still blocking what they claim to block.
- `/write-spec`: Turn a loose request into a written spec, problem, scope, behaviour, acceptance criteria, that /ce-plan can consume without guessing.

Seven come with the Next.js stack in every repo: `/verify`, `/write-spec`, `/qa-feature`, `/deploy-to-vercel`, `/security-audit`, `/landing-copy` and `/help`. Every design adds `/new-component`. The rest come from the batteries you pick. Stripe brings `/add-plan` and `/test-webhook` ([Stripe battery](/with/stripe)). Neon brings `/db-branch` and `/migrate-on-neon` ([Neon battery](/with/neon)).

Here is the start of `/test-webhook`. The first lines say why the skill exists before a single command. The full file ends with a "Report back with" list:

````markdown
---
description: Exercise the Stripe webhook endpoint locally. Forward real events with the CLI, buy a subscription and a one-time price, refund one, assert idempotency, and debug signature failures.
name: test-webhook
---

Prove that `/api/webhooks/stripe` verifies signatures, handles the events this
app cares about, and does the right thing when the same event arrives twice.

Nothing in my-app records a subscription or a purchase for good except
a webhook, so "it worked in Checkout" is not evidence. (The success page asks
Stripe directly to show the plan sooner, but it sends no receipt and it only
runs when the buyer comes back.) This is.

## 1. Start the loop

Two terminals.

```bash
# terminal 1
bun run dev

# terminal 2
bun run stripe:listen
```

The listener prints:

```
Ready! Your webhook signing secret is whsec_xxxxxxxx
```
````

*First 30 of 233 lines of `.claude/skills/test-webhook/SKILL.md`.*

The generator also writes each skill for Codex (`.agents/skills/<name>/SKILL.md`) and for Cursor (`.cursor/rules/skill-<name>.mdc`, loaded on request). Same content, three targets.

## Skills vs slash commands

They are the same thing now. Claude Code merged custom commands into skills. A file at `.claude/commands/deploy.md` and a skill at `.claude/skills/deploy/SKILL.md` both create `/deploy`.

Your old `.claude/commands/` files keep working. Skills add three things commands never had:

- A folder for supporting files.
- Frontmatter that decides who can run it, you, Claude, or both.
- Auto-loading when Claude decides it is relevant.

Write new ones as skills.

## Skills vs subagents

A skill is instructions. A subagent is a worker.

| | Skill | Subagent |
|---|---|---|
| What it is | Instructions, a workflow or reference | A separate Claude with its own prompt and tools |
| Context | Loads into your conversation | Runs in its own context window |
| What comes back | Everything it does stays in your thread | Only a summary |
| Best for | Procedures, checklists, reference | Work that reads a lot, or needs fewer tools |

They combine both ways. A skill with `context: fork` runs inside a subagent. A subagent with a `skills:` list starts with those skills already loaded.

The generated repo does a version of this. `/security-audit` is a skill that runs the pass through the `security-auditor` subagent. The skill holds the procedure. The subagent holds the narrow tool list. More in [Claude Code subagents](/guides/claude-code-subagents).

## Skills vs CLAUDE.md, rules and hooks

| Put it in | When |
|---|---|
| `CLAUDE.md` | Claude needs it on every task: build commands, project layout |
| A path-scoped rule | It applies to every edit in some folder |
| A skill | It is a procedure, or reference you need sometimes |
| A hook | It must happen, or never happen, every single time |

A skill that says "never edit `.env`" is a request. A hook that blocks the edit is enforcement. See [Claude Code hooks](/guides/claude-code-hooks) and the full [Next.js setup](/guides/claude-code-setup-nextjs).

## Claude Code skills best practices

- **Write the description for the router.** Say what it does and when to use it. Lead with the main use case.
- **One job per skill.** Name it as a verb: `/add-table`, `/test-webhook`, `/db-branch`.
- **Steps are exact commands.** Numbered, in order, with the real script names.
- **Write the failure branches.** What to do when step 3 errors is the part people need most.
- **End with a check.** A skill that cannot tell you whether it worked is not finished.
- **Fix the output format.** "Report back with" beats "summarize your work".
- **Keep `SKILL.md` under 500 lines.** Move reference into separate files and link them.
- **Turn off auto-run for side effects.** Deploys, emails, migrations: `disable-model-invocation: true`.
- **Keep `allowed-tools` narrow.** `Bash(git log *)`, not `Bash`.
- **Read before writing.** The best skills open the relevant code and docs before they act.

The test for a new skill: you explained it twice. The third time, write it down.

## Common mistakes

- **A vague description.** "Helps with the database" never loads at the right time. Name the trigger.
- **Rules dressed up as skills.** "Always use the server client in `src/db/**`" is a [path-scoped rule](/guides/claude-code-setup-nextjs), not a procedure.
- **Guardrails as skills.** Claude reads skills and decides. Hooks run regardless.
- **A wiki in one file.** A 1,000-line `SKILL.md` costs the whole thing on every run. Split it.
- **No verification step.** The agent reports "done" and nobody knows.
- **Auto-run deploys.** One fuzzy request and Claude ships to production. Gate it.
- **Copy-pasted overlap.** Two skills with similar descriptions make Claude pick the wrong one.

## Get these skills in your repo

Pick your batteries in the [builder](/build), or run:

```bash
npm create agentic-boilerplate@latest my-app
```

You get the skills for your picks, plus the rules, subagents, guard hooks and solution docs that go with them. Every battery has to ship at least one skill to get in. Start from [Indie SaaS](/stack/indie-saas) to get the 28 above. The layer is explained in [the agentic layer docs](/docs/the-agentic-layer), and the generated `CLAUDE.md` lists every skill (see the [CLAUDE.md template](/guides/claude-md-template)).

## FAQ

### What is a Claude Code skill?

A skill is a `SKILL.md` file with YAML frontmatter, in its own folder under `.claude/skills/`. You run it by name, like `/verify`, and Claude can load it on its own when your request matches its description.

### Where do Claude Code skills go?

Project skills go in `.claude/skills/`, one folder per skill, and get committed with the repo. Personal skills go in `~/.claude/skills/` and work in every project.

### What is the difference between skills and slash commands?

None that matters now. Custom commands were merged into skills, so `.claude/commands/deploy.md` and `.claude/skills/deploy/SKILL.md` both create `/deploy`. Skills add supporting files, invocation control and auto-loading.

### What is the difference between Claude Code skills and agents?

A skill is instructions that load into your conversation. A subagent is a separate worker with its own context, prompt and tools, and it returns only a summary. A skill can run in a subagent with `context: fork`.

### How does Claude decide to use a skill?

It matches your request against each skill's description, which is in context from the start. Set `disable-model-invocation: true` to make a skill run only when you type its name.

### Do skills work in Codex and Cursor?

Skills follow the Agent Skills open standard. The generator writes each skill three ways: `.claude/skills/` for Claude Code, `.agents/skills/` for Codex, and one rule per skill in `.cursor/rules/` for Cursor.


## Sources

- [Claude Code docs: Skills](https://code.claude.com/docs/en/skills)
- [Claude Code docs: Extend Claude Code](https://code.claude.com/docs/en/features-overview)
- [Claude Code docs: Subagents](https://code.claude.com/docs/en/sub-agents)

## Generate it

[Build your repo](https://agenticboilerplate.com/build)

---

Agentic Boilerplate: A Next.js repo your agent already knows. Free during launch, then $99 once.

- Site map for agents: https://agenticboilerplate.com/llms.txt
- Public API: https://agenticboilerplate.com/openapi.json
- Contact: agenticstudio@gmail.com
