Claude Code skills examples: 5 SKILL.md files you can copy

Five complete Claude Code skills (commits, PR review, tests, debugging and a report) with their SKILL.md and why each one works.

Claude Code skills examples: 5 SKILL.md files you can copy

A Claude Code skill example is a folder with a SKILL.md file: at the top, between two --- lines, a name and a description that say what it does and when to use it; below that, the steps in Markdown. That’s enough for Claude to trigger it on its own or for you to call it with /skill-name.

To follow this post you only need to know what a skill is (if not, start with what a skill is and how it differs from a prompt) and to have opened Claude Code, Anthropic’s assistant that works from your terminal at least once. I won’t repeat the theory here: we’re going to look at complete Claude skills examples, ready to copy.

This is the shortest one I find useful:

---
name: explicar-codigo
description: Explains a piece of code in plain language for a beginner. Use it when the user asks what some code does or asks for it to be explained.
---

1. Summarize in one sentence what the code does.
2. Walk through it block by block, without using jargon you haven't explained.
3. Finish with an example input and the output it produces.

Save it to .claude/skills/explicar-codigo/SKILL.md and /explicar-codigo now exists (if the .claude/skills/ folder didn’t exist when you opened the session, run /reload-skills first). Everything else you’ll see is a variation on this shape.

What each example teaches

Each example teaches a different idea (last column).

SkillWhat it’s forWho triggers itWhat it teaches
mensaje-commitConventional Commits messagesClaude or youInjecting a command’s output with !
revisar-prReviewing a PR with the team checklistClaude or youReceiving arguments with $ARGUMENTS
generar-testsTests in the project’s styleClaude or youAn instructions-only skill
depurar-errorFinding the cause before touching codeClaude or youA procedure with a loop
informe-semanalA report built from the commitsOnly youdisable-model-invocation and a supporting file

Five Claude Code skills you can copy

They all follow the format in the official documentation [1] and their frontmatter passes a YAML parser.

1. Commit messages that follow a convention

So that every commit follows the same convention without anyone having to remember it (what makes a message good is covered in best practices for commit messages).

---
name: mensaje-commit
description: Writes commit messages following Conventional Commits based on the staged changes. Use it when the user asks to make a commit, write a commit message or review what is staged.
allowed-tools: Bash(git diff *) Bash(git status *)
---

## Staged changes
!`git diff --staged --stat`

## How to write the message
1. If nothing is staged, say so and stop. Do not run `git add` on your own.
2. Pick the type: feat, fix, docs, refactor, test or chore.
3. First line: `type(scope): imperative summary`, 72 characters max.
4. Optional body: why the change was made, not what changed.
5. Show the message and wait for my confirmation before running `git commit`.

Why it works: the staging area is what you’ve already prepared with git add, and the line starting with ! runs git diff --staged --stat before Claude reads the skill, with its output replacing the line, so Claude gets the real changes [1]. allowed-tools approves those commands for the turn in which you invoke the skill (your message and everything Claude does until it replies); if an injected command isn’t allowed, the invocation is aborted and Claude never reads the skill. git commit is left out on purpose: Claude still asks your permission before committing. The type(scope): description shape and the feat and fix types come from Conventional Commits, which allows additional types such as docs or chore [2].

2. Reviewing a PR with your checklist

If your team always reviews pull requests with the same questions, those questions are begging to become a skill.

---
name: revisar-pr
description: Reviews a GitHub pull request against the team checklist and returns findings by priority. Use it when the user asks to review a PR or a GitHub pull request before approving it.
argument-hint: "[pr-number]"
allowed-tools: Bash(gh pr diff *) Bash(gh pr view *)
---

Review PR $ARGUMENTS.

1. Read the description with `gh pr view $ARGUMENTS` and the diff with `gh pr diff $ARGUMENTS`.
2. Go through this checklist, in order:
   - Does the change do what the description says?
   - Are there tests for the new behavior?
   - Does any secret, `console.log` or commented-out code slip in?
   - Does any name force you to read the body to understand it?
3. Return the findings in two groups: "Blocks the merge" and "Suggestion".
4. Each finding includes file, line and a concrete proposal.
5. Do not approve or comment on GitHub: only report.

Why it works: with /revisar-pr 42, Claude Code replaces every $ARGUMENTS with 42 [1]; argument-hint is just the autocomplete hint. You need the gh CLI installed and authenticated. Step 5 is the one I’m most grateful for, because a comment posted in your name on a teammate’s PR, without you having read it, is exactly what you don’t want.

3. Generating tests in the project’s style

No special fields: just instructions, which is what most skills look like.

---
name: generar-tests
description: Writes unit tests with Vitest following the project's conventions. Use it when the user asks for tests for a function or a module.
---

1. Find an existing test near the file and copy its style (imports, names, mocks).
2. Write one `describe` per function and one `it` per behavior.
3. Cover the happy path, at least one edge case and one error case.
4. Name each test after what it checks: `it('returns 0 when the list is empty')`.
5. Run `npx vitest run <file>` and don't consider the task done until it passes.

Why it works: step 1 makes Claude imitate your repo (including its mocks, the fake pieces that stand in for a real dependency in a test) instead of its generic idea of a test, and step 3 asks for at least one edge case (an input at the boundary, like an empty list). Step 5 gives it an objective definition of done. Using Jest or pytest? Change the description and the command in step 5.

4. Debugging an error with a procedure

When you paste a stack trace (the list of calls leading up to the error), the model’s temptation is to fix the first thing it sees. This skill forces it to go step by step.

---
name: depurar-error
description: Investigates an error or a failing test with a root-cause procedure before touching any code. Use it when the user pastes a stack trace or an error message, or says something has stopped working.
---

Follow these steps in order and don't skip any:

1. Reproduce the error with a specific command. If it doesn't reproduce, stop and ask.
2. Read the full message and the stack trace. Point out the first line that is our code.
3. Write a hypothesis in one sentence and how you will test it.
4. Test it by reading code or adding a temporary log. If it fails, go back to step 3.
5. Write a test that reproduces the error and check that it fails.
6. Fix it with the minimal change and check that the test passes.
7. Remove the temporary logs and summarize: cause, fix and test added.

Why it works: the description captures how you actually ask for help (“it stopped working”, a pasted stack trace) and step 4 is a loop with a clear exit. The “don’t skip any” is written as a standing instruction because Claude Code doesn’t reread the file in later turns [1].

5. Weekly report from a template

This last one I never want running automatically: a report gets generated when I ask for it.

---
name: informe-semanal
description: Generates the team's weekly progress report from the commits of the last seven days across all branches.
disable-model-invocation: true
allowed-tools: Bash(git log *)
---

## This week's commits
!`git log --all --since="7 days ago" --oneline --no-merges`

## Instructions
1. Group the commits by topic, not by author.
2. Fill in the template from [plantilla.md](plantilla.md) without adding sections.
3. If a section ends up empty, write "Nothing this week" instead of making something up.

The template lives next to it, in .claude/skills/informe-semanal/plantilla.md:

# Weekly report

## Done
- 

## In progress
- 

## Blockers
- 

Why it works: with disable-model-invocation: true the description doesn’t even enter Claude’s context, so it only runs when you type /informe-semanal [1]. Claude reads the template only when it needs it: long material that takes up no context until then. One detail: --all reads the branches you have locally, including the remote ones you’ve fetched, so run git fetch first to see the whole team’s work.

The pattern behind the five examples

Strip away the specifics and they all share the same anatomy. A description that says what the skill does and in what words someone would ask for it. A body with numbered steps that are short and checkable. And, when needed, one of these extras: data injected with !, arguments, tool permissions or a supporting file.

Anthropic’s guide adds two details: write the description in the third person (“Reviews a PR”, not “I can review your PR”) and keep SKILL.md under 500 lines, with the long material in separate files [3]. In Claude Code the name is optional and defaults to the folder name, but if you write it in lowercase letters, numbers and hyphens, up to 64 characters, the skill also works in other Claude products [1] [3].

Mistakes you’ll run into

A vague description. “Helps with tests” doesn’t tell Claude when to step in; the description has to contain the words you’d use to ask for it [1].

A skill for something that should always apply. A permanent rule belongs in CLAUDE.md or in a hook (a command Claude Code always runs on an event, whether the model asks for it or not); I go into this in when to use skills, CLAUDE.md or hooks in Claude Code.

Broken frontmatter. If the YAML doesn’t parse, the skill loads without metadata: /skill-name still works, but Claude can no longer match your request against the description [1]. A stray colon inside the description is enough to break it, so wrap it in quotes if it has one.

How to create a skill in Claude Code: where to save it and how to test it

To create a skill in Claude Code all you need is the folder and the SKILL.md. A project skill goes in .claude/skills/skill-name/SKILL.md inside the repo, and the whole team gets it when you commit. A personal one goes in ~/.claude/skills/skill-name/SKILL.md and you have it in all your projects. If the names clash, the personal one wins over the project one [1].

No restart needed: Claude Code picks up changes in those folders while you work. The exception is a .claude/skills/ folder that didn’t exist when you opened the session: Claude Code isn’t watching it yet, so run /reload-skills to load it and repeat that after every change until you restart [1]. To test it:

  1. Type /skills and check that it shows up.
  2. Invoke it by hand with /skill-name to see that the body does what you expect.
  3. Open a new session and ask for the task in your own words, without naming the skill, to see whether the description triggers it.
  4. If it doesn’t kick in, rewrite the description using those words and repeat the previous step.

The new session matters: whatever stays in the context while you write the skill papers over the gaps in the instructions. Once you have several skills, tools and an agent loop at the same time, the question becomes which piece to use for what; that’s what we practice in the Agentic Patterns course, composing skills, tools and loops with sound judgment. And if you’re torn between a skill and an MCP server for a task, the comparison is in MCP vs Skills.

Sources

  1. Extend Claude with skills, Claude Code Docs: SKILL.md format, frontmatter fields, locations, invocation with /skill-name, $ARGUMENTS, injection with !, allowed-tools, disable-model-invocation, reloading and troubleshooting.
  2. Conventional Commits 1.0.0 specification: the type(scope): description structure and the feat, fix and additional types.
  3. Skill authoring best practices, Claude Docs: limits on name and description, third-person descriptions, the suggested 500-line limit.

Frequently Asked Questions

Can I write a skill’s description in a language other than English?

Yes. The documentation doesn’t require a language; my rule of thumb is to write it in the language you’ll use to ask for things, because Claude matches your request against that text.

What’s the difference between a skill and a command in .claude/commands?

Both create a /skill-name: a .claude/commands/deploy.md file and a .claude/skills/deploy/SKILL.md skill give you the same /deploy. Commands still work, but the documentation recommends skills for anything new because they support supporting files; with the same name, the skill wins.

Why doesn’t my Claude Code skill trigger on its own?

It’s almost always the description: it doesn’t contain the words you used to ask. Also check that it doesn’t have disable-model-invocation: true and that the frontmatter parses; if the YAML is broken, the skill loads without a description and Claude has nothing to match it against.

Can a skill run commands without asking my permission?

Beyond whatever your permission rules already allow, the ones listed in allowed-tools, and only during the turn in which you invoke it: the permission is cleared with your next message, and a deny or ask rule of yours still takes precedence. That field applies even if you haven’t accepted trust for the directory, so read it in any skill that ships in a repo before opening Claude Code in it; I cover the underlying risk in skills and MCP as a supply chain.

How long should a SKILL.md be?

Just long enough for the procedure. The five in this post fit on one screen, and Anthropic’s guide sets the ceiling at 500 lines; anything beyond that goes into separate files the skill links to.