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
- Narrow scope - one job, done well. “Do everything” skills get ignored.
- Clear trigger - description is the ONLY thing Claude sees when deciding to load. Be specific.
- Deterministic commands - exact commands, exact paths. Don’t make Claude guess.
- 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.