Writing your own Claude Code skills — zero to MVP in 30 minutes
A skill is a small markdown file that adds a slash command with dedicated logic to Claude Code. Showing how to write one from scratch, where to put it, and which mistakes to avoid.

In the previous skills post I covered which ones are worth having. Now I'll show how to write one from scratch. Spoiler: it's a markdown file with frontmatter. Nothing more.
What a skill is
A skill is a slash command definition (/my-action). It has:
- a name
- a description (when to fire)
- a system prompt for the agent when fired
- optionally: tools whitelist, model override, scripts
The file lives at ~/.claude/skills/{name}.md (global) or .claude/skills/{name}.md (per project).
Anatomy of a skill
Minimal example:
---
name: archive-week
description: Archive all closed Vikunja tasks from the last week
allowed-tools:
- mcp__vikunja__*
---
Your job:
1. Find all tasks in status "done" closed in the last 7 days
2. For each — set label "archived" and move to project "Archive"
3. Show a summary: how many, which projects
Do not delete any task. Ever./archive-week in the terminal runs this prompt with the Vikunja MCP whitelist only. Safe and narrow.
Skill #1: review a specific file
---
name: review-file
description: Code review of a specific file, focus on readability and error handling
arguments:
- name: file
description: Path to the file
required: true
---
Read file {{file}} and review with focus on:
1. **Readability**: variable names, function length, structure
2. **Error handling**: silent failures, error propagation
3. **Security**: SQL injection, command injection, XSS
4. **Consistency**: does it match the rest of the repo
Be brief. Each issue with a line (path:line). Don't suggest style "nits" — the linter does that.Usage: /review-file src/auth/login.ts. Structured feedback in 30 seconds.
Skill #2: quick commit
---
name: quick-commit
description: Commit all changes with an auto-generated message
allowed-tools:
- Bash
---
1. Run `git status` and `git diff --cached` (after add)
2. Generate a concise, descriptive commit message (title max 72 chars, body optional)
3. Commit WITHOUT asking to confirm the message
4. Return only hash and message
Message format: `<type>: <description>`
Types: feat, fix, refactor, docs, chore, style, test/quick-commit after editing = one keystroke, commit done.
Skill #3: deploy demo
---
name: deploy-demo
description: Build and deploy a demo on the forge PC
arguments:
- name: slug
description: Demo slug (folder name)
required: true
allowed-tools:
- Bash
---
Run sequentially:
1. SSH to forge: `ssh [email protected]`
2. `cd /home/kkaletka/demo-{{slug}}`
3. `docker compose up -d --build`
4. Check `curl localhost:$(cat .port)` — must return 200
5. Update Cloudflare ingress if new subdomain
6. Telegram notify when ready
If any step fails — STOP, report the error, do not continue./deploy-demo misiura instead of 6 manual commands.
Pitfalls when writing skills
1. Too broad a description. If the description says "performs various tasks", the agent fires the skill on everything. Rule: description = one concrete scenario.
2. No allowed-tools. By default a skill has access to all tools. The "tidy tasks" skill has no reason to have Bash or file editing. Whitelist minimally.
3. Assuming the agent remembers context. A skill starts a fresh session. Anything it needs, must be in the prompt or the agent collects it itself. "Keep previous state" doesn't work.
4. Arguments without validation. If a skill takes slug as an argument and uses it in bash, the agent may inject. Always write in the prompt " must match [a-z0-9-]+, otherwise reject".
Where to put them
- Global (
~/.claude/skills/): universal skills, review, commit, generic deploy - Per project (
.claude/skills/): project-specific,/deploy-blog,/run-tests-watch
Per project is usually better. You ship the skills with the project (commit to repo), no manual config needed.
What I have
Currently ~12 active skills. Most used:
/quick-commit/review-file/deploy-demo/archive-week/audit-deps(npm audit + pip-audit aggregated)
Each < 50 lines of markdown. ~500 lines total, gives me maybe 3 hours per week.
A skill is the cheapest mechanism to extend Claude Code. A markdown file, a few minutes. If you repeat something more than 3 times a week, write a skill. The bar is so low the "no time" excuse doesn't hold.