Writing Claude Code skills

Claude Code skills = bundles of instructions (+ optional scripts) teaching Claude one specific job in your env. → One of the highest-leverage customizations available.

Mental model

Skill = folder with SKILL.md at the top.

my-skill/
├── SKILL.md         # Frontmatter + instructions
├── scripts/         # Optional helper scripts
│   └── run.py
└── references/      # Optional reference docs
    └── api.md

→ Frontmatter tells Claude when to load. → Body tells Claude how to execute.

---
name: my-skill
description: Use this when the user asks to do X in context Y.
---

Step 1: ...
Step 2: ...

What makes a good skill

  1. Narrow scope - one job, done well. “Do everything” skills get ignored.
  2. Clear trigger - description is the ONLY thing Claude sees when deciding to load. Be specific.
  3. Deterministic commands - exact commands, exact paths. Don’t make Claude guess.
  4. Safe by default - prefer read-only. WARNING: destructive steps need explicit confirmation.

Minimal example

---
name: deploy-staging
description: Use when the user asks to deploy to staging. Runs the build, pushes to the staging branch, and tails the deploy logs.
---

1. Run `npm run build` - fail fast if it errors.
2. `git push origin HEAD:staging --force-with-lease`
3. `gh run watch --exit-status` to watch the deploy workflow.
4. Report the deploy URL from the workflow output.

Testing

→ Fastest feedback loop: run Claude Code in a throwaway repo, ask it to do the thing. → Claude ignores the skill? Description is wrong. → Claude loads but fumbles? Body is wrong.

Lesson: a skill is a contract - the description recruits Claude, the body executes the work. Get both right or get nothing.