--- title: Skill vs Plugin type: concept updated: 2026-04-28 --- # Skill vs Plugin When to ship a capability as a bare `SKILL.md` vs as a full Claude Code plugin. ## What a plugin can ship A plugin is a bundle. It can include any of: | Component | Purpose | Loadable any other way? | |---|---|---| | **Skills** (`skills//SKILL.md`) | Behavioral guidance for Claude | Yes — copy to `~/.claude/skills/` | | **Slash commands** (`commands/.md`) | `/foo` invocations | **No** — only via plugin manifest | | **Hooks** (`hooks/`) | `session-start`, `pre-tool-use`, etc., executed by the harness | **No** — must be in plugin | | **Sub-agents** (`agents/.md`) | `Agent { subagent_type: "" }` | **No** — only via plugin | | **MCP servers** (`.mcp.json`) | Adds tools like `mcp__context7__*` | Manual `~/.claude/settings.json`, but loses versioning/marketplace ops | | **Output styles, statusline, etc.** | Cosmetic / harness config | **No** | | **Versioning + release notes** | `/plugin update X` flow | **No** | A bare `SKILL.md` is just one row in that table — the first one. ## When the bare skill is enough If the artifact is *only* `SKILL.md` files (with optional `assets/`, `references/`): - A folder under `~/.claude/skills//` works. - Distribute via `.skill` archive (zip) or copy the folder. - All 13 skills in this repo are bare skills. No plugin needed. ## When you actually need a plugin Any of: - **A slash command.** `/brainstorm`, `/commit`, `/loop`. Only path is `commands/.md` in a plugin. - **A hook.** Auto-load behavior on session start / prompt submit / post-tool-use. Hooks fire from the harness, not from Claude. Plugin manifest is how the harness finds them. - **A sub-agent type.** Plugin manifest is how `Agent` discovers it. - **MCP server registration.** Yes, you can shove it into `~/.claude/settings.json` manually (we did this for context7 originally). But the official plugin gets you marketplace ops — `/plugin install`, `/plugin update`, `/plugin uninstall` — which manual JSON doesn't. - **Versioning + marketplace path.** Consumers can pull updates without chasing. ## Real example: `superpowers` The official `superpowers` plugin ships: | Component | Count | Notes | |---|---|---| | Skills | 14 | Could live as bare skills | | Slash commands | 3 | `/brainstorm`, `/execute-plan`, `/write-plan` — only via plugin | | Hooks | 4 | Includes `session-start` | | Sub-agents | 1 | `code-reviewer` | The killer feature: the `session-start` hook auto-injects `using-superpowers` content at the top of every session. That's why we see `superpowers:brainstorming`, `superpowers:writing-plans`, etc. listed in `available_skills` from the very first message — without anyone saying "use superpowers". Bare-skill copies can't do that. ## Decision flow ``` Want to ship a capability → Only SKILL.md content? → bare skill (skills//, install via copy/zip) Need /? → plugin Need a session-start (or other) hook? → plugin Need a subagent_type? → plugin MCP server with /plugin update? → plugin (see context7-setup.md) ``` ## What this means for *this* repo All 13 of our skills are currently bare. None ships slash commands, hooks, or sub-agents — so no plugin format is needed today. The moment to reconsider: if we want a `/caveman` slash command, or a `session-start` hook that auto-loads `active-platform` based on `uname`, or a sub-agent like a "skill-tester". At that point — wrap the relevant skills into a plugin and publish through a marketplace (own or `claude-plugins-official` if that channel becomes available). ## See also - [context7-setup.md](context7-setup.md) — concrete example of switching a manual MCP registration to a plugin (and the cost: re-injecting `--api-key` after `/plugin update`).