What makes a good skill

At its core, a Claude Code skill is a markdown file — SKILL.md — that gets loaded into Claude's context when you invoke it. Claude reads the file, understands the instructions, and executes accordingly. There is no runtime, no compiled binary, and no plugin API. The entire skill is a prompt.

That simplicity is also a constraint. Because SKILL.md is pure instruction, the quality of a skill depends entirely on how clearly it communicates three things:

Before writing a single line, browse the existing skill directory for inspiration. Notice how the best skills are narrow, opinionated, and specific about their output format.

Skill folder structure

A publishable skill is a folder with a predictable layout. Only SKILL.md is required; everything else is optional but encouraged for larger skills.

Skill folder layout
my-skill/ ├── SKILL.md ← required: the main instruction file ├── README.md ← for humans browsing GitHub or the directory ├── metadata.json ← structured metadata (name, version, tags) ├── scripts/ ← executable helpers Claude can run via Bash │ └── check-env.sh ├── references/ ← long reference docs loaded on demand │ └── api-schema.md └── templates/ ← reusable output templates └── report.md

Keep the root clean. Only files that Claude needs to read or execute belong here. Documentation for contributors goes in README.md; long reference material that would bloat the main context goes in references/. The skills.sh CLI zips the entire folder when publishing, so avoid committing secrets, node_modules, or large binaries.

Tip: The ZIP that users download is generated from the skill folder automatically. Keep it lean — a smaller download installs faster and signals that your skill is well-scoped.

Write your SKILL.md

The SKILL.md file has two parts: a YAML frontmatter block that provides machine-readable metadata, and a markdown body that provides human- and Claude-readable instructions.

Frontmatter

The three required frontmatter fields are name, description, and version. Everything else is indexed by skills.sh but not required for local use.

Body sections

Structure the body with three core sections. You can add more, but these three are the minimum for a skill that behaves consistently:

Here is a complete, annotated example for a skill that audits environment variables before a deployment:

SKILL.md — full example
--- name: env-audit description: > Audit environment variables in this project before a deployment. Checks for missing required vars, insecure defaults, and secrets accidentally committed to version control. version: 1.0.0 author: your-handle tags: [devops, security, environment] --- # env-audit Audit environment variables for safety and completeness before deploying. ## When to Use Invoke this skill before any deployment command — local, staging, or production. Use it when: - Adding a new service that requires environment variables - Onboarding a new developer who needs to configure their .env - Preparing a production release checklist Out of scope: secret rotation, CI/CD pipeline configuration. ## How It Works 1. List all `.env*` files in the project root (`.env`, `.env.local`, `.env.example`, `.env.production`, etc.). 2. Parse each file for key-value pairs. Ignore comments and blank lines. 3. Cross-reference `.env.example` as the source of truth for required keys. Flag any key present in `.env.example` but missing from `.env`. 4. Scan for common insecure defaults: empty values, placeholder strings (`changeme`, `your-secret-here`, `TODO`), and keys ending in `_SECRET` or `_KEY` that match known weak patterns. 5. Check that `.env` and `.env.local` are listed in `.gitignore`. Warn if any `.env*` file (except `.env.example`) is tracked by git. 6. Produce the audit report (see Output Format). ## Output Format A markdown report with three sections: ### Missing Variables Table of keys in `.env.example` not found in `.env`, with the default value from `.env.example` if present. ### Security Warnings Bulleted list of insecure values or git-tracked secrets. Each item includes the file path, key name, and reason. ### Summary One-line verdict: "All clear — N variables checked, no issues found." or "N issue(s) found. Review warnings above before deploying."

Notice what this example does not do: it does not try to fix the problems it finds, it does not touch CI configuration, and it does not manage secrets storage. Staying in that narrow lane is what makes it reliable.

Test your skill locally

Before publishing, verify the skill works exactly as intended on your own machine. The skills CLI supports installing directly from a local folder path.

Install from a local path
npx skills add ./my-skill -y

The -y flag skips the confirmation prompt. After installation, open Claude Code in any project and invoke the skill with its slash command:

Invoke in Claude Code
/env-audit

Run through your intended use cases and check whether the output matches what you specified in the Output Format section. Common iteration points:

Reinstall after each change with the same command — the CLI will overwrite the previous version. See the install guide for more detail on the installation lifecycle.

Note: Local installs do not create a skills.sh entry. They only affect your own Claude Code environment. Nothing is uploaded until you run npx skills publish.

Add scripts and references

For many skills, SKILL.md alone is enough. But two optional folders let you extend what a skill can do without bloating the main instruction file.

scripts/

Put executable helpers here when the skill needs to run shell commands that are too long or complex to describe inline. Scripts are not run automatically — you must tell Claude to run them in your SKILL.md instructions. Keep scripts POSIX-compliant when possible so they work on macOS and Linux without modification.

Good candidates for scripts: environment checks, dependency version validators, file format converters, report generators that require jq or awk.

references/

Put long reference documents here when Claude needs access to a spec, schema, or policy that would be too large to paste into SKILL.md. Reference files are not loaded automatically — instruct Claude to read the relevant file when it needs it: "If the API schema is needed, read references/api-schema.md."

Good candidates for references: OpenAPI specs trimmed to relevant endpoints, internal style guide excerpts, compliance checklists, data model definitions.

Publish to skills.sh

Once you are satisfied with local testing, publishing takes three steps.

1. Push to GitHub

Create a public repository with your skill folder at the root (or as a named subfolder if you are publishing multiple skills from one repo). The README.md will be shown on your skills.sh profile page, so make it clear and useful.

2. Run npx skills publish

Publish to skills.sh
npx skills publish

The CLI reads your metadata.json and SKILL.md frontmatter, packages the folder into a ZIP, and submits it to skills.sh. You will be prompted to authenticate with your GitHub account on the first publish.

3. The review process

skills.sh runs an automated quality check when a skill is submitted. The check validates that SKILL.md is present, that frontmatter is complete, and that no secrets or large binary files are included in the package. Skills that pass automatically are listed within a few minutes. Skills that fail the check receive a structured error response explaining what to fix.

Manual review is only triggered for skills flagged by the automated system or reported by users. There is no approval queue for clean submissions.

After publishing: Your skill will appear in the directory with an install link. Share it — the download count updates in real time.

FAQ

Does SKILL.md need frontmatter?

Frontmatter is strongly recommended but not strictly required. Without it, skills.sh cannot index your skill's name, version, or description, so it won't appear correctly in search results or the directory. Always include at minimum name, description, and version fields.

Can a skill call external APIs?

Yes. A skill can instruct Claude to use tools like Bash, curl, or fetch to reach external APIs. Just be explicit in your SKILL.md about what credentials or environment variables are needed. Users need to have those configured before the skill will work correctly.

How do I version my skill?

Use semantic versioning (e.g. 1.0.0, 1.1.0, 2.0.0) in the frontmatter version field and in metadata.json. Increment the patch version for small fixes, the minor version for new capabilities, and the major version for breaking changes to the interface or output format.

What's the difference between a skill and a CLAUDE.md?

CLAUDE.md is a project-level instruction file that Claude reads automatically in any project that contains it — it sets persistent context, rules, and preferences for that codebase. A skill is an on-demand module you install and invoke explicitly with a slash command. Skills are portable and shareable; CLAUDE.md is project-specific.