How to Create a Claude Code Skill: Build One With Me (2026)

A hands-on tutorial to write your first Claude Code skill — the real SKILL.md format, where it lives, how it triggers, and a working example built step by step.

By Shen Huang··6 min read·
claude codeclaude code skillstutorialai codingagentic coding

I maintain lich-skills, a collection of skills I use across a dozen projects, and the question I get most is the plainest one: how do I actually write one? Not the theory — the file. This is a build-one-with-me tutorial. By the end you'll have a real, working skill on disk and you'll understand every line of it.

If you're still fuzzy on the concept, read what is a Claude Code skill first — it's a two-minute primer. If you just want to install other people's skills, how to install Claude Code skills covers that. This post is about authoring your own.

The skill we'll build: a conventional-commit helper that teaches the agent to write commit messages the way I like them. Small, real, and something you'll actually keep.

Step 1: The anatomy of a skill

A skill is a folder with one required file: SKILL.md. That's the whole spec at its core.

conventional-commit/
└── SKILL.md          # YAML frontmatter + markdown instructions

Bigger skills add scripts/, references/, and examples/ subfolders that the agent loads on demand — but you don't need any of that to ship something useful. One markdown file is a complete skill.

The file has two parts: a YAML frontmatter block at the top (metadata Claude reads to decide when to use the skill) and a markdown body (the instructions it follows once it does). The critical design fact — and the thing most first-timers get wrong — is that the body doesn't load into context until Claude decides the skill is relevant. It makes that decision by matching your prompt against the description field. So the description isn't decoration; it's the trigger.

Step 2: Write the metadata

Create the folder and open the file:

mkdir -p ~/.claude/skills/conventional-commit
$EDITOR ~/.claude/skills/conventional-commit/SKILL.md

Now the frontmatter. Per the official Claude Code docs, only two fields matter for a basic skill — name and description:

---
name: conventional-commit
description: Write a git commit message in Conventional Commits format. Use when the user asks to commit, write a commit message, or stage changes with a proper type prefix like feat, fix, or chore.
---

Three rules to get this right:

  • name must match the folder name and stay under 64 characters, kebab-case. It also becomes the slash-command name — you'll be able to fire this skill manually with /conventional-commit.
  • description is load-bearing. Write it in the third person and pack it with the trigger words your future self will actually type — "commit", "commit message", "stage changes". If the description is vague ("helps with git"), Claude won't know when to reach for it. If it's specific, it activates at exactly the right moment and stays invisible the rest of the time.
  • Don't invent fields. The frontmatter supports a documented set — allowed-tools to restrict which tools the skill may call, and disable-model-invocation to make a skill fire only when you call it by name, among a few others. If you're not sure a field exists, leave it out. The two above are all you need today.

Step 3: Write the instructions

Below the closing ---, write the body as plain markdown. Treat it like an onboarding doc for a sharp new teammate: second-person imperative, numbered steps, and explicit guardrails.

When the user asks to commit, do this:

1. Run `git diff --staged` to see what's actually staged. If nothing
   is staged, run `git status` and ask which files to include.
2. Pick ONE Conventional Commits type that fits the change:
   feat, fix, refactor, docs, style, test, chore, build, ci, perf.
3. Write the subject line as `type(scope): summary` — imperative
   mood, lower-case, no trailing period, under 72 characters.
4. If the change is non-trivial, add a blank line then 1–3 bullet
   points explaining WHY, not what.
5. Show me the message and wait for confirmation before running
   `git commit`.

NEVER commit with `--no-verify`. NEVER bundle unrelated changes
into one commit — suggest splitting instead.

Two things carry a lot of weight here. First, the NEVER lines — the model reads negative guardrails faithfully, and they prevent the exact failure modes you've been burned by before. Second, the "wait for confirmation" step keeps a human in the loop for the one action that touches your git history. Keep the whole body focused on a single capability. A skill that tries to "handle all of git" will underperform; one that "writes a good commit message" will nail it every time.

Step 4: Place it and let Claude find it

Where the folder lives decides the scope:

# Personal — available in every project on this machine
~/.claude/skills/conventional-commit/SKILL.md

# Project — checked into the repo, shared with your team
<repo>/.claude/skills/conventional-commit/SKILL.md

Use the personal path for your own habits, the project path for conventions the whole team should share (commit it to git and everyone gets it on clone). Claude Code discovers skills at launch, so restart your session — or start a fresh one — after creating the file.

Step 5: Test it

Two ways to confirm it works. Force it explicitly first:

/conventional-commit

If the slash command shows up in the menu, your frontmatter parsed cleanly. Now test the part that actually matters — automatic triggering. Stage a change and type the way you normally would:

> commit these changes

If your description is doing its job, Claude loads the skill on its own and produces a feat(scope): … message following your rules. If it doesn't trigger, that's almost always a description problem, not a body problem — go back and add the words you'd naturally use.

Step 6: Iterate

First drafts are always too long or too vague. Tighten in this order:

  • Trigger misses? Widen the description with more real phrasings. Trigger too often? Narrow it.
  • Agent ignores a rule? Promote it to a NEVER/ALWAYS line, or move it earlier in the body — position matters.
  • Body creeping past a screen or two? Split the reference material into a references/patterns.md file the agent pulls only when needed, and keep SKILL.md lean.

That's the whole loop: write, place, restart, test, tighten. A skill is never really "finished" — it just gets sharper each time it annoys you.

Where to go next

You now have a complete skill and the muscle memory to write the next one in five minutes. The fastest way to level up is to read good ones — browse 2,000+ community skills for structure and phrasing you can borrow, and see the best Claude Code skills of 2026 for the patterns that stuck. Most of my most-installed skills started exactly like this one: a small fix to a recurring annoyance.

Want a short, opinionated read on what's actually worth building each week? I send one every Monday — subscribe to the weekly. No noise, just the few things builders needed to know.

NEWSLETTER · FREE · WEEKLY

OrangeBot Weekly

The best new AI tools + Claude Code skills, every week — with my verdict on what’s actually worth your time. No hype.

Free · One-click unsubscribe · No spam

READ OTHER ARTICLES