Plugin Development Guide

Complete guide for building third-party Han plugins, covering plugin structure, configuration, skills, commands, hooks, and distribution.

This guide walks you through creating Han plugins from scratch. Whether you're building validation hooks, specialized agents, or MCP integrations, you'll find everything you need here.

Quick Start

The fastest way to create a new plugin is with the han create plugin command:

# Interactive mode - prompts for all options
han create plugin

# Non-interactive mode
han create plugin --category validation --name biome --description "Biome linting and formatting" --author "Your Name"

This scaffolds a complete plugin structure with all required files.

Plugin Categories

Han plugins are organized into nine categories based on their technical layer:

CategoryDirectoryPurposeExamples
Corecore/Essential infrastructurecore, bushido
Languagelanguages/Programming language supporttypescript, python, rust
Frameworkframeworks/Framework integrationsreact, nextjs, django
Validationvalidation/Linting, formattingbiome, eslint, prettier
Tooltools/Build tools, testingplaywright, jest, docker
Integrationservices/MCP servers for external servicesgithub, gitlab, linear
Disciplinedisciplines/Specialized AI agentsfrontend, backend, security
Patternpatterns/Methodologies, workflowsai-dlc, tdd, atomic-design
Specializedspecialized/Niche toolsandroid, ios, tensorflow

Plugin Structure

What a Han plugin typically contains:

your-plugin/
├── .claude-plugin/
│   └── plugin.json      # Plugin manifest
├── han-plugin.yml       # Han hook configuration (optional)
├── hooks/
│   └── hooks.json       # Generated from han-plugin.yml
├── skills/              # Skills (optional)
│   └── skill-name/
│       └── SKILL.md
├── agents/              # Agents for discipline plugins (optional)
│   └── agent-name.md
├── .mcp.json            # MCP server config for integration plugins
├── README.md            # Documentation
└── CHANGELOG.md         # Version history

The Full Claude Code Component Set

Han plugins use a subset of what Claude Code supports. The complete set of components a plugin can ship, and where each lives:

ComponentLocationHan's usage
Manifest.claude-plugin/plugin.jsonRequired by Han's marketplace
Skillsskills/<name>/SKILL.mdHan's convention for plugin knowledge
Commandscommands/<name>.mdSkills as flat markdown. Valid, but no Han plugin uses it
Agentsagents/<name>.mdUsed by discipline plugins
Hookshooks/hooks.jsonGenerated from han-plugin.yml
MCP servers.mcp.jsonUsed by integration plugins
LSP servers.lsp.jsonNot modeled by Han
Workflowsworkflows/Not modeled by Han
Output stylesoutput-styles/Not modeled by Han
Themesthemes/Experimental upstream. Not modeled by Han
Monitorsmonitors/monitors.jsonExperimental upstream. Not modeled by Han
Executablesbin/Files here join the Bash tool's PATH and are invokable as bare commands while the plugin is enabled. Not modeled by Han
Settingssettings.jsonDefault configuration applied when the plugin is enabled. Only the agent and subagentStatusLine keys are supported. Not modeled by Han

"Not modeled by Han" means Han's own tooling does not generate or validate the component; Claude Code still loads it normally if your plugin ships one.

Two notes on the ones that overlap with Han's conventions:

  • commands/ is accepted by Claude Code, so a plugin containing one is not invalid. It is not Han's convention: every plugin in the marketplace uses skills/ with a SKILL.md, and none ships a commands/ directory. Write a skill unless you specifically need explicit /command invocation.
  • hooks/hooks.json should be generated with han plugin generate-hooks rather than hand-written, so han-plugin.yml stays the single source of truth.

Everything except .claude-plugin/plugin.json lives at the plugin root, not inside .claude-plugin/.

Required Files

plugin.json

Every plugin must have a .claude-plugin/plugin.json file:

{
  "name": "biome",
  "version": "1.0.0",
  "description": "Brief description of what your plugin does",
  "author": {
    "name": "Your Name",
    "url": "https://your-website.com"
  },
  "homepage": "https://github.com/you/your-plugin",
  "repository": "https://github.com/you/your-plugin",
  "license": "MIT",
  "keywords": ["keyword1", "keyword2"]
}

Required fields:

  • name: Unique plugin name (use category-appropriate naming)
  • version: Semantic version (semver)
  • description: Brief description shown in marketplace

Optional fields:

  • author: Author information
  • homepage: Plugin homepage URL
  • repository: Source code repository
  • license: License identifier (MIT, Apache-2.0, etc.)
  • keywords: Search terms for marketplace discovery

Next Steps