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-checkplugin that validates environment config before deploys - A
migration-helperplugin that knows your database migration patterns - A
style-checkplugin 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.