Claude Code Boilerplate
FeaturesPricingDocsBlog
Get started →

Product

  • Features
  • Pricing
  • Skills
  • Roadmap

Compare

  • vs ShipFast
  • vs MakerKit
  • vs supastarter

Resources

  • Docs
  • Blog
  • Discord

Legal

  • License
  • Refund Policy
  • Privacy Policy
  • Terms of Service
Claude Code Boilerplate

© 2026 Claude Code Boilerplate. All rights reserved.

← All posts

Writing Claude Code skills -- how to build your own step-by-step skill files

May 18, 2026
claude-codeskills

Writing Claude Code skills -- how to build your own step-by-step skill files

A Claude Code skill is a markdown file that Claude reads and executes as a precise, repeatable instruction set. Skills are what make the difference between asking Claude to "add a feature" and getting inconsistent results, versus running /feature-module task and getting 7 correctly structured files every time.

This post covers how to write skill files that Claude actually follows -- the structure, the step patterns, and the small details that prevent drift.

What a skill is

A skill is a .md file in .claude/skills/ (or .claude/commands/). When you type /skill-name in Claude Code, Claude reads the file and executes its instructions.

The difference between a skill and a regular prompt:

  • A prompt is typed once and forgotten. A skill is stored and reusable.
  • A skill can be shared with the whole team via the repo. Everyone gets the same behavior.
  • Claude reads the skill fresh each time, so the instructions are always in context.
  • Skills can include conditionals, file reads, API calls, and multi-step sequences.

If you find yourself repeating the same multi-step prompt more than twice, write a skill.

File location and naming

.claude/
  skills/
    feature-module/
      SKILL.md          <-- full skill instructions
    nextjs-api-route/
      SKILL.md
  commands/
    generate-post.md    <-- simpler single-file format

Both locations work. Use skills/<name>/SKILL.md for complex skills with supporting files. Use commands/<name>.md for shorter, self-contained skills.

The filename (without extension) becomes the slash command. feature-module/SKILL.md is invoked with /feature-module.

Anatomy of a skill file

Skills in .claude/skills/<name>/SKILL.md use YAML frontmatter followed by markdown content:

Frontmatter (required):

---
name: feature-module
description: One sentence describing what this skill does and when Claude should trigger it automatically.
---

Title -- a short H1 after the frontmatter:

# Feature Module Skill

Steps -- the core of the skill, numbered and explicit:

  1. Read an existing module in modules/ to understand the structure.
  2. Create modules/<name>/<name>.schema.ts with a pgTable definition.
  3. ...

Usage -- shows Claude the expected argument format:

/feature-module <name>

Example:
/feature-module categories

The simpler .claude/commands/<name>.md format skips frontmatter entirely. The first line is the description, followed directly by a steps section. Use it for short, self-contained skills.

Use the skills/ format when you want Claude to auto-trigger the skill from context -- the description frontmatter field is what Claude matches against.

Writing steps Claude will follow

The quality of a skill comes down to how you write its steps. These patterns work:

Be explicit about file paths. Vague instructions drift.

Bad:

Create the schema file for the module.

Good:

Create modules/<name>/<name>.schema.ts with a pgTable definition.
Table name: plural snake_case. Export name: camelCase + Table suffix (e.g. taskTable).

Specify what to read before writing. If the skill depends on existing conventions, tell Claude to read them.

  1. Read db/drizzle.ts to understand how schemas and relations are registered.
  2. Read an existing module (e.g. modules/post/) to understand the 7-file structure.
  3. Create the new module following the same pattern.

List every file to create. Do not say "scaffold the module" -- say exactly which files.

Create these 7 files:

  • modules/<name>/<name>.schema.ts
  • modules/<name>/<name>.relations.ts
  • modules/<name>/<name>.types.ts
  • modules/<name>/<name>.validation.ts
  • modules/<name>/<name>.repo.ts
  • modules/<name>/<name>.service.ts
  • modules/<name>/index.ts

Include the side effects. If creating a file requires updating another file, say so explicitly.

After creating the schema, add an export to db/schema.ts:

export * from '../modules/<name>/<name>.schema';

After creating the relations file, import and spread it into the db client in db/drizzle.ts.

Use <name> as a placeholder. Claude replaces it with the argument from the slash command. This is the standard convention across all boilerplate skills.

Conditional logic

Skills can branch based on what Claude finds:

  1. Check if modules/<name>/ already exists.
    • If yes: stop and tell the user the module already exists.
    • If no: proceed with creation.
  2. Check if the user passed a second argument (e.g. /nextjs-api-route GET /api/tasks).
    • If a method and path were provided: generate a route handler for that method.
    • If only a path was provided: generate GET and POST handlers.

Claude handles this branching in natural language -- no if/else syntax needed.

Reading files within a skill

Skills can instruct Claude to read files before acting:

  1. Read CLAUDE.md and find the "Blog Style Guide" section. Use the voice, keywords, and stop words defined there when generating the post.
  2. Read .env and extract AI_API_KEY (do not hardcode the value).
  3. Fetch http://localhost:3000/api/posts to get existing post slugs. Do not create a post whose title overlaps with an existing one.

This is how the generate-post skill works: it reads style conventions, checks for overlap, then creates the post -- all in one invocation.

Making skills ASCII-safe

If a skill generates content that will be stored in a database or sent over an API, add an explicit ASCII constraint:

  • Use only ASCII characters in all generated text.
  • Replace em dashes with --, smart quotes with straight quotes ("/').
  • Replace ellipsis characters with ....
  • Never output Unicode beyond U+007F.

Without this, Claude occasionally outputs Unicode punctuation that breaks JSON serialization or causes display issues in terminals.

Usage section format

Always include a Usage section at the bottom of the skill. It shows Claude the expected argument format:

Single argument:

/feature-module <name>

Example:
/feature-module categories

Multiple argument patterns:

/nextjs-api-route <METHOD> <path>
/nextjs-api-route <path>   (generates GET + POST)

Examples:
/nextjs-api-route POST /api/tasks
/nextjs-api-route /api/tasks/:id

A minimal working skill

Here is a complete skill that scaffolds a new React component. Create it at .claude/skills/new-component/SKILL.md:

Frontmatter:

---
name: new-component
description: Scaffold a new React component following the project's UI conventions.
---

Title + steps:

Title: # New Component Skill

Steps:

  1. Read an existing component in components/ to understand the structure.
  2. Create components/<name>/<name>.tsx:
    • Named export (not default)
    • Props typed with an interface: interface <Name>Props { ... }
    • Use cn() from lib/utils for classname merging
    • Use CSS variables for colors, never hardcoded hex values
    • Add "use client" only if the component needs event handlers or hooks
  3. If the component has subcomponents, co-locate them: components/<name>/<SubName>.tsx
  4. Do not modify files in components/ui/ -- those are shadcn components.

Usage section:

## Usage

/new-component <name>

Example:
/new-component PricingCard

Connecting skills to CLAUDE.md

Skills and CLAUDE.md complement each other. CLAUDE.md defines your conventions globally -- naming rules, architecture patterns, anti-patterns. Skills reference those conventions rather than repeating them.

For example, a skill step can say: "Follow the naming conventions defined in CLAUDE.md" -- then list the specific rules:

  • Table names are plural (tasks, users)
  • Column names are snake_case
  • TypeScript exports are camelCase + Table suffix

This keeps skills short and ensures they stay in sync with your conventions automatically. If you update a convention in CLAUDE.md, every skill that references it picks up the change.

For a full guide on writing CLAUDE.md, see "How to configure CLAUDE.md for a Next.js project."

Takeaway

A good skill is explicit about paths, files, and side effects. It tells Claude what to read before writing. It uses <name> as a placeholder and includes a Usage section with examples. Write one any time you repeat a multi-step prompt more than twice -- the investment pays back immediately.