How to write your own Claude skill (with examples)

6 min read
Alireza Bashiri
Alireza Bashiri
Founder
How to write your own Claude skill

After launching the AstroMVP skill marketplace, the second most common question I get (after "which skill should I buy") is "how do I write my own?" Good question. If you have deep expertise in a specific domain, packaging that into a skill file is one of the highest leverage things you can do.

I've written every skill in our store. Here's the framework I use.

What a skill file actually is

Strip away the branding and a Claude skill is a structured text document. That's it. No SDK. No API. No special file format. It's a file that your AI agent reads as context, and the patterns in that file influence how the agent generates code.

The magic isn't in the format. It's in what you put inside. A skill file with vague advice produces vague code. A skill file with specific architecture decisions, concrete code patterns, and real-world examples produces code that looks like a senior developer wrote it.

The anatomy of a skill file

Every good skill file has five sections. You can name them whatever you want, but the structure matters.

1. Metadata and scope

Start by telling the agent exactly what this skill covers and what it doesn't. Be specific. If your skill is about building a SaaS app with Next.js and Supabase, say that. If it doesn't cover mobile apps or Python backends, say that too.

# SaaS Builder Skill

## Scope
This skill covers building full-stack SaaS applications using:
- Next.js 14+ (App Router)
- Supabase (auth, database, storage)
- Stripe (billing)
- Tailwind CSS + shadcn/ui

## Out of scope
- Mobile apps (see iOS Mobile Builder skill)
- Python/Django backends
- WordPress or PHP

The scope section prevents your agent from going off-track. Without it, the agent might try to apply SaaS patterns to a mobile app, which wastes tokens and produces weird output.

2. Architecture patterns

This is the meat. Describe how the application should be structured. Not just the file structure, but the reasoning behind each decision.

## Architecture

### File structure
/app - Next.js App Router pages and layouts
/app/api - API routes (server-side only)
/app/(auth) - Auth-related pages (login, signup, reset)
/app/(dashboard) - Authenticated dashboard pages
/components - Reusable UI components
/components/ui - shadcn/ui primitives
/lib - Utility functions and configurations
/lib/supabase - Supabase client and server helpers

### Why this structure
Group routes by auth state using route groups.
(auth) pages use a minimal layout without nav.
(dashboard) pages use a full layout with sidebar.
This prevents layout flickering during auth transitions.

Notice the "why" section. This is what separates a skill from a template. Templates show you what to do. Skills explain why, which means the agent can adapt the pattern to your specific situation instead of copy-pasting blindly.

3. Code patterns

Include specific code snippets for the patterns you want the agent to follow. These should be real, working code from production apps.

## Auth Pattern

### Server-side auth check
Always check auth on the server, never rely on client-side only.

\`\`\`typescript
// lib/supabase/server.ts
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'

export async function getUser() {
  const cookieStore = cookies()
  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    { cookies: { get: (name) => cookieStore.get(name)?.value } }
  )
  const { data: { user } } = await supabase.auth.getUser()
  return user
}
\`\`\`

### Why this approach
- getSession() can be spoofed client-side
- getUser() makes a server call to verify the token
- Always use getUser() for auth checks in server components

The code snippets should be complete enough to use but focused enough to illustrate one pattern at a time. Don't dump your entire codebase into a skill file. Pull out the 15 to 20 patterns that matter most.

4. Naming conventions and standards

AI agents love consistency but they'll pick random conventions unless you specify them. Lock these down.

## Conventions

### Naming
- Components: PascalCase (UserProfile.tsx)
- Utilities: camelCase (formatDate.ts)
- API routes: kebab-case (/api/create-checkout)
- Database tables: snake_case (user_profiles)
- Environment variables: SCREAMING_SNAKE_CASE

### Error handling
- Always wrap API calls in try/catch
- Return typed error objects, never throw raw errors
- Log errors server-side with context (user ID, action, timestamp)
- Show user-friendly messages client-side, never raw error strings

5. Examples and anti-patterns

Show the agent what good looks like and what bad looks like. Anti-patterns are surprisingly effective because they tell the agent exactly what to avoid.

## Anti-patterns (DO NOT do these)

### Bad: Client-side auth check only
if (session) { showDashboard() }
// This can be bypassed. Always verify server-side.

### Bad: Inline Stripe keys
const stripe = new Stripe('sk_live_abc123')
// Never hardcode keys. Use environment variables.

### Bad: No error boundary
// Every page should have an error.tsx file
// Without it, errors crash the entire app

A complete mini skill example

Here's a condensed skill file for building a simple waitlist page. This is simpler than our production skills but shows the structure:

# Waitlist Page Skill

## Scope
Build a waitlist landing page with email collection using
Next.js, Supabase, and Tailwind CSS.

## Architecture
Single page app with:
- Hero section with headline and email input
- Social proof counter showing current signups
- Thank you state after submission

File structure:
/app/page.tsx - Main waitlist page
/app/api/waitlist/route.ts - API endpoint for submissions
/app/layout.tsx - Root layout with metadata
/components/WaitlistForm.tsx - Email form component
/lib/supabase.ts - Supabase client

## Database
Table: waitlist
Columns: id (uuid), email (text, unique), created_at (timestamp)
Add a unique constraint on email to prevent duplicates.

## Code Patterns

### Form submission
Use server actions or API route. Validate email server-side.
Return specific error for duplicate emails ("You're already on the list").
Show success state with confetti or animation.

### Social proof
Query count of waitlist entries and display it.
Update count optimistically on successful submission.
Format: "Join 847 others on the waitlist"

## Anti-patterns
- Don't use client-side only validation
- Don't store emails without sanitization
- Don't show raw database errors to users
- Don't forget meta tags and OG image for sharing

That's about 200 words and it's enough to produce a solid waitlist page. A production skill like our SaaS Builder is 10x longer because it covers 10x more patterns, but the structure is identical.

Tips from writing 9 production skills

Be opinionated. The worst skill files are the ones that say "you could do A or B." Pick one. The agent needs a clear direction, not a menu of options.

Use real code from real apps. Don't write theoretical examples. Pull patterns from apps that are live and handling real users. The agent can tell the difference (not literally, but real patterns have edge cases handled that theoretical ones don't).

Update your skills. I revise our skills every time I learn something from a customer build. The SaaS Builder skill has been updated 4 times since launch. Each update makes the output better.

Test with multiple prompts. Write your skill, then test it with 5 different project descriptions. If the output is consistently good across all 5, the skill is solid. If it falls apart on certain prompts, you have gaps to fill.

Want a custom skill without writing it yourself?

The MVP Mega Bundle includes a custom skill request. You describe your use case and I write the skill file for you. It's the fastest way to get a production-grade skill tailored to your specific project.

Or take what you've learned here and write your own. The format is simple. The hard part is having the domain expertise to fill it with patterns that actually work. If you've built real things, you already have that.


Frequently Asked Questions

What format should a Claude skill file be in?

Plain text or Markdown. There's no special format or SDK required. The key is structuring the content with clear sections: metadata, architecture patterns, code patterns, naming conventions, and examples. The AI agent reads it as context and follows the patterns.

How long should a Claude skill file be?

Most effective skill files are between 2,000 and 10,000 words. Too short and the agent doesn't have enough context. Too long and important patterns get buried. Focus on the 20% of patterns that cover 80% of use cases.

Can I sell my own Claude skills?

Yes. You can sell skill files on platforms like OpenClaw or your own website. If you have deep expertise in a specific domain, packaging that knowledge into a skill file is a legitimate product.

Do Claude skills work with AI agents other than Claude?

Yes. A skill file is just structured instructions. Any AI coding agent that accepts context files can use it, including Claude Code, Cursor, Windsurf, and others. The patterns are agent-agnostic.