Swiftbeard

Building Your First Claude Code Plugin

A step-by-step approach to building a Claude Code plugin from scratch — skills, commands, and hooks.

claude-codepluginsskillstutorial

Building a Claude Code plugin is simpler than the documentation suggests. The barrier is understanding the model, not the implementation. This is a concrete walkthrough.

What You're Building

Let's build a pr-ready plugin that does a pre-PR checklist:

  • Checks for common issues (console.logs, TODO comments, hardcoded values)
  • Generates a PR description from recent commits
  • Suggests a reviewer based on the files changed

The Directory Structure

.claude/
  skills/
    pr-ready/
      skill.yaml
      commands/
        pr-ready.md
      context/
        pr-standards.md

Create this in your project root. Skills can also go in ~/.claude/skills/ to be global across all projects.

Step 1: The Manifest

skill.yaml is the entry point:

name: pr-ready
version: 1.0.0
description: "Pre-PR checklist and PR description generator"
author: "your-name"

commands:
  - name: pr-ready
    description: "Run pre-PR checklist and generate PR description"
    file: commands/pr-ready.md

context:
  - file: context/pr-standards.md
    scope: always  # Load this context in every session

scope: always means the context file is injected into every Claude session in this project. Use this for project-wide conventions. scope: command would only load context when the command is invoked.

Step 2: The Command

commands/pr-ready.md is the system prompt for the /pr-ready command:

# PR Ready Check

You are a senior developer doing a pre-merge review.

Run the following steps:

## Step 1: Code Smell Check
Run: `git diff main...HEAD -- '*.ts' '*.tsx' '*.py'`

Look for:
- console.log() or print() statements that shouldn't be in production
- TODO/FIXME/HACK comments that block merging
- Hardcoded URLs, API keys, or environment-specific values
- Commented-out code blocks

Report findings as a list. Mark each: [BLOCKER] or [WARNING].

## Step 2: PR Description
Run: `git log main...HEAD --oneline`
Run: `git diff --stat main...HEAD`

Generate a PR description:
- Title: imperative, present tense, under 60 chars
- Summary: 2-3 sentences on what changed and why
- Changes: bulleted list of key changes
- Testing: what was tested

## Step 3: Reviewer Suggestion
Run: `git diff --name-only main...HEAD`

Based on the files changed, suggest 1-2 reviewers.
Use git log to find who has modified these files most recently:
`git log --follow --format="%ae" -- <filename> | head -5`

Format output clearly with each section labeled.

Step 3: Context File

context/pr-standards.md is loaded in every session:

# PR Standards for This Project

## Required Before Merging
- All tests pass (run: npm test)
- No TypeScript errors (run: npm run type-check)
- PR description follows our template
- At least one reviewer approved

## Code Conventions
- No console.log in production code (use our logger)
- All async functions must have error handling
- API endpoints must have input validation via Zod

## Branch Naming
- feature/description
- fix/description
- chore/description

Step 4: Testing It

# In your project directory
claude  # Start a Claude Code session

# The context is automatically loaded
# Run your command
/pr-ready

Claude will execute the git commands, analyze the output, and produce your checklist and PR description.

Adding a Hook

Hooks fire automatically without needing to run a command. Add this to your skill.yaml to run a quick check before every commit:

hooks:
  - trigger: PreToolUse
    matcher: "Bash(git commit*)"
    prompt: |
      Before this commit, quickly check:
      1. Are there any console.log statements in staged files? (git diff --cached)
      2. Any TODO comments that should block commit?

      If yes, warn the user. If no, proceed silently.

Now every time Claude Code runs a git commit, it runs this check first and warns if it finds something.

The Pattern Generalizes

Once you understand this structure — manifest, commands, context, hooks — you can build plugins for anything:

  • A deploy-check plugin that validates environment config before deploys
  • A migration-helper plugin that knows your database migration patterns
  • A style-check plugin that enforces your specific code style conventions

The key is that skills externalize your team's knowledge into Claude's context, rather than having to re-explain conventions every session. Write it once, load it always.