How to Create a Custom Plugin for Claude Code: A Complete Developer Guide
Creating a custom Claude Code plugin requires a .claude-plugin directory containing a plugin.json manifest, a skills/ folder with markdown-based knowledge units, and an optional commands/ folder for slash-invoked workflows.
Claude Code plugins are file-based packages that extend the AI assistant's capabilities through structured skills and commands. Based on the reference implementation in the phuryn/pm-skills repository, you can build and distribute plugins without compiling binaries or writing complex code. This guide walks through how to create a custom plugin for Claude Code using the exact specifications found in the source code.
Understanding the Plugin Anatomy
Claude Code recognizes plugins through a strict convention-based directory layout. The repository demonstrates that every plugin must reside in its own folder with specific metadata and content subdirectories.
Required Directory Structure
A valid plugin requires the following hierarchy:
my-plugin/ # Root folder of your plugin
├─ .claude-plugin/ # Metadata directory (required)
│ └─ plugin.json # Manifest describing the plugin
├─ skills/ # One-folder-per-skill (markdown files)
│ └─ my-skill/
│ └─ SKILL.md # Skill definition (YAML front-matter + description)
└─ commands/ # Optional slash-commands (markdown)
└─ my-command.md
The Manifest File (plugin.json)
The plugin.json file serves as the plugin's entry point. According to the reference implementation at pm-toolkit/.claude-plugin/plugin.json, the manifest must include specific metadata fields:
{
"name": "pm-toolkit",
"version": "2.0.0",
"description": "PM utility skills …",
"author": {
"name": "Paweł Huryn",
"email": "[email protected]",
"url": "https://www.productcompass.pm"
},
"keywords": ["product-management","resume","legal","nda","privacy-policy","copywriting"],
"homepage": "https://www.productcompass.pm",
"license": "MIT"
}
Skills vs Commands
Skills are markdown files stored in skills/<skill-name>/SKILL.md that contain YAML front-matter and instructional content for the model. The review-resume skill in pm-toolkit/skills/review-resume/SKILL.md demonstrates the required format with a YAML header containing name: and description: fields followed by instructional content.
Commands are optional markdown files placed in the commands/ directory that define slash-prefixed workflows (e.g., /my-command) that Claude Code executes when invoked.
Building Your First Custom Plugin
Step 1: Initialize the Directory Structure
Create your plugin root folder and the required subdirectories:
mkdir -p my-plugin/.claude-plugin
mkdir -p my-plugin/skills/hello-world
mkdir -p my-plugin/commands
Step 2: Configure the Plugin Manifest
Create my-plugin/.claude-plugin/plugin.json with the minimum required fields:
{
"name": "my-plugin",
"version": "0.1.0",
"description": "A starter plugin showing how to expose a single skill.",
"author": {
"name": "Your Name",
"email": "[email protected]",
"url": "https://yourwebsite.com"
},
"keywords": ["example","custom","plugin"],
"homepage": "https://github.com/youruser/yourrepo",
"license": "MIT"
}
Step 3: Create Your First Skill
Create my-plugin/skills/hello-world/SKILL.md with a YAML front-matter block followed by markdown content:
---
name: hello-world
description: "Greets the user and explains the purpose of the plugin."
---
# Hello World Skill
You are a friendly assistant. When invoked, respond with:
Hello! This is the hello‑world skill from the my‑plugin plugin. How can I help you today?
The skill does not require any input arguments.
Step 4: Add Optional Slash Commands
If your plugin requires workflow automation, create a command file at my-plugin/commands/example.md. These files define the slash-command name and the workflow that Claude Code executes when the command is invoked.
Publishing and Distributing Plugins
Creating a Plugin Marketplace
For distributing multiple plugins or making your plugin discoverable, create a marketplace manifest at your repository root. The phuryn/pm-skills repository uses .claude-plugin/marketplace.json to list available plugins:
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "pm-skills",
"version": "2.0.0",
"description": "Structured AI workflows …",
"owner": { "name": "...", "email": "...", "url": "..." },
"plugins": [
{
"name": "pm-toolkit",
"description": "PM utility skills …",
"source": "./pm-toolkit",
"category": "product-management"
}
]
}
The source field specifies the relative path from the repository root to the plugin directory.
Installing Custom Plugins in Claude Code
Once your plugin is hosted in a Git repository, users can install it via the Claude Code CLI. First, optionally add the marketplace:
claude plugin marketplace add phuryn/pm-skills
Then install your specific plugin:
claude plugin install [email protected]/youruser/yourrepo
If you published a full marketplace, users can add it once and then install any listed plugin by name:
claude plugin install <plugin-name>
Summary
- Plugins are file-based packages that require a
.claude-plugin/plugin.jsonmanifest and askills/directory containing markdown files. - Skills use YAML front-matter followed by instructional content, as demonstrated in
pm-toolkit/skills/review-resume/SKILL.md. - Optional commands extend functionality with slash-prefixed workflows stored in
commands/*.md. - Marketplaces aggregate multiple plugins using a root-level
.claude-plugin/marketplace.jsonfile. - Installation uses the CLI commands
claude plugin marketplace addandclaude plugin install.
Frequently Asked Questions
What is the minimum required structure for a Claude Code plugin?
A functional plugin requires only two components: a .claude-plugin/plugin.json manifest file and at least one skill folder containing a SKILL.md file. The manifest defines metadata like name and version, while the skill file contains the YAML front-matter and instructional content that Claude Code uses to perform tasks.
Do I need to create a marketplace to distribute my plugin?
No, you can distribute individual plugins directly from any Git repository using the claude plugin install <plugin-name>@github.com/<user>/<repo> command. Marketplaces are optional and only necessary if you want to bundle multiple plugins together or make them discoverable through the marketplace add command.
How do I update a plugin after publishing changes?
Update the version field in your plugin.json manifest, commit the changes, and push to your repository. Users can then update their local installation using the Claude Code CLI update commands. The plugin system reads the manifest directly from the repository, so no compilation or build step is required.
Can I use private repositories for custom plugins?
Yes, Claude Code can access plugins from private repositories if the user has appropriate Git credentials configured. The CLI uses standard Git authentication to fetch plugin files, so private plugins work seamlessly provided the user has read access to the repository containing the .claude-plugin directory.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →