# How to Create a Custom Plugin for Claude Code: A Complete Developer Guide

> Learn to create a custom Claude Code plugin. This guide covers the essential .claude-plugin directory structure, manifest files, and knowledge units for developers.

- Repository: [Pawel Huryn/pm-skills](https://github.com/phuryn/pm-skills)
- Tags: how-to-guide
- Published: 2026-07-02

---

**Creating a custom Claude Code plugin requires a `.claude-plugin` directory containing a [`plugin.json`](https://github.com/phuryn/pm-skills/blob/main/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`](https://github.com/phuryn/pm-skills/blob/main/plugin.json) file serves as the plugin's entry point. According to the reference implementation at [`pm-toolkit/.claude-plugin/plugin.json`](https://github.com/phuryn/pm-skills/blob/main/pm-toolkit/.claude-plugin/plugin.json), the manifest must include specific metadata fields:

```json
{
  "name": "pm-toolkit",
  "version": "2.0.0",
  "description": "PM utility skills …",
  "author": {
    "name": "Paweł Huryn",
    "email": "pawel@productcompass.pm",
    "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`](https://github.com/phuryn/pm-skills/blob/main/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:

```bash
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`](https://github.com/phuryn/pm-skills/blob/main/my-plugin/.claude-plugin/plugin.json) with the minimum required fields:

```json
{
  "name": "my-plugin",
  "version": "0.1.0",
  "description": "A starter plugin showing how to expose a single skill.",
  "author": {
    "name": "Your Name",
    "email": "you@example.com",
    "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`](https://github.com/phuryn/pm-skills/blob/main/my-plugin/skills/hello-world/SKILL.md) with a YAML front-matter block followed by markdown content:

```markdown
---
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`](https://github.com/phuryn/pm-skills/blob/main/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`](https://github.com/phuryn/pm-skills/blob/main/.claude-plugin/marketplace.json) to list available plugins:

```json
{
  "$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:

```bash
claude plugin marketplace add phuryn/pm-skills

```

Then install your specific plugin:

```bash
claude plugin install my-plugin@github.com/youruser/yourrepo

```

If you published a full marketplace, users can add it once and then install any listed plugin by name:

```bash
claude plugin install <plugin-name>

```

## Summary

- **Plugins are file-based packages** that require a [`.claude-plugin/plugin.json`](https://github.com/phuryn/pm-skills/blob/main/.claude-plugin/plugin.json) manifest and a `skills/` directory containing markdown files.
- **Skills use YAML front-matter** followed by instructional content, as demonstrated in [`pm-toolkit/skills/review-resume/SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/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.json`](https://github.com/phuryn/pm-skills/blob/main/.claude-plugin/marketplace.json) file.
- **Installation** uses the CLI commands `claude plugin marketplace add` and `claude 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`](https://github.com/phuryn/pm-skills/blob/main/.claude-plugin/plugin.json) manifest file and at least one skill folder containing a [`SKILL.md`](https://github.com/phuryn/pm-skills/blob/main/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`](https://github.com/phuryn/pm-skills/blob/main/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.