Someone writes a useful skill, it lives on their machine, and two weeks later a colleague solves the same problem from scratch. That is the pattern most teams fall into.
The previous post covered how to write skills for Claude Code: a SKILL.md file that teaches Claude a workflow, living in your home directory where it applies to every project you work on, or committed to a project’s .claude/skills/ directory so everyone who clones the repo gets it too. Both setups work well within their scope. They break down the moment a skill needs to follow someone across projects, or reach a team that doesn’t share one repo.
This post covers the next layer: plugins, marketplaces, and keeping shared skills alive as the team grows.
Packaging skills as plugins
Skills can live in three places: your home directory for personal use, a project repo for team-specific knowledge, or a plugin for anything that needs to follow a developer across multiple projects.
A plugin is a directory with a plugin.json manifest that groups related skills into a single installable unit. Install the plugin, you get everything in it, so put the wrong skills together and everyone who installs gets capabilities they did not ask for.
Plugins can also bundle slash commands, subagents, MCP server configurations, and hooks, though you can start with just skills.
A dev-tools plugin containing three everyday development skills looks like this:
dev-tools/
├── .claude-plugin/
│ └── plugin.json
└── skills/
├── review-pr/
│ └── SKILL.md
├── write-tests/
│ └── SKILL.md
└── explain-code/
└── SKILL.md
The plugin.json manifest looks like this:
{
"name": "dev-tools",
"version": "1.0.0",
"description": "Everyday development workflows"
}
The manifest only needs a name to identify the plugin. You don’t need to list skills individually since Claude Code auto-discovers them in the skills/ directory, but the version field matters a lot once you start distributing plugins to other people (see “Versioning shared plugins” below).
Once installed, each skill is namespaced by the plugin name: review-pr becomes dev-tools:review-pr.
How to decide what goes in a plugin
Group by who installs it. A developer writing application code has different needs from someone on the security team, and that gap is a trust boundary too. A security plugin containing a scan-dependencies skill should not be installed on every developer’s machine, even if it goes unused. Scanning dependencies for known vulnerabilities needs access to the org’s vulnerability database, and that access belongs with the security team. Separating by plugin makes the access decision explicit: you install what you need. check-logs is a different case: it is read-only and useful to anyone troubleshooting a production issue, not just the security team, so it belongs in its own observability plugin with wider access rather than sharing security’s narrower scope. dev-tools, with skills like review-pr, write-tests, and explain-code, is safe for everyone.
Within a plugin, lean toward grouping skills that always travel together. If a developer who wants review-pr would always want write-tests as well, they belong in the same plugin. If two skills are only occasionally used together or target different roles, separate plugins give each team the option to install only what applies to them.
Distributing plugins with a marketplace
Any team following that grouping ends up with more than one plugin, and once you do, you need a way to catalog them and let people discover what’s available.
A plugin packages one or more skills into a single installable unit.
A marketplace catalogs one or more plugins and points Claude Code to where each one lives.
A marketplace is a Git repository with a marketplace.json file at its root.
This example combines both roles in one repo: acme-corp/claude-plugins is the marketplace, and it also holds the dev-tools, security, and observability plugins under plugins/, matching their source values below.
acme-corp/claude-plugins/
├── .claude-plugin/
│ └── marketplace.json
└── plugins/
├── dev-tools/
│ ├── .claude-plugin/plugin.json
│ └── skills/
│ ├── review-pr/SKILL.md
│ ├── write-tests/SKILL.md
│ └── explain-code/SKILL.md
├── security/
│ ├── .claude-plugin/plugin.json
│ └── skills/
│ └── scan-dependencies/SKILL.md
└── observability/
├── .claude-plugin/plugin.json
└── skills/
└── check-logs/SKILL.md
The marketplace.json file looks like this:
{
"name": "acme-marketplace",
"owner": { "name": "DevTools Team" },
"metadata": { "pluginRoot": "./plugins" },
"plugins": [
{
"name": "dev-tools",
"source": "dev-tools",
"description": "Standard development workflows"
},
{
"name": "security",
"source": "security",
"description": "Security team skills: dependency vulnerability scanning"
},
{
"name": "observability",
"source": "observability",
"description": "Read-only log access for troubleshooting"
}
]
}
Each plugin’s source value is just the name of its directory under plugins/. The pluginRoot setting is what lets those be bare names instead of full relative paths.
A team member adds the marketplace once, from their terminal:
claude plugin marketplace add acme-corp/claude-plugins
Then installs plugins from inside a Claude Code session:
/plugin install dev-tools@acme-marketplace
They can also browse all available plugins interactively with /plugin.
This distribution pattern is not exclusive to Claude Code. OpenAI Codex has its own plugin marketplace: run /plugins inside a Codex CLI session to browse, install, and toggle plugins that bundle skills and MCP configs. Google’s Gemini CLI has an extensions gallery at geminicli.com/extensions/browse, installed with gemini extensions install <github-repo-url>, where an extension can bundle MCP servers, custom commands, and agent skills. Both tools use the term skills for the same file-based unit described in the Agent Skills specification, which lists Codex and Gemini CLI among its adopters, but each vendor built a separate marketplace and plugin manifest format on top. A plugin packaged for Claude Code will not install into Codex or Gemini CLI without repackaging.
Adding the marketplace to a project automatically
Manual installation still requires people to know the marketplace exists. The better approach is to add it to the project’s .claude/settings.json and commit that file:
{
"extraKnownMarketplaces": {
"acme-marketplace": {
"source": {
"source": "github",
"repo": "acme-corp/claude-plugins"
}
}
},
"enabledPlugins": {
"dev-tools@acme-marketplace": true
}
}
When a team member opens the project and trusts the folder (Claude Code’s permission prompt when opening a new project directory), Claude Code registers the marketplace automatically. It does not install the listed plugins on its own: for each one, Claude Code reports it as not installed and shows the exact claude plugin install command to run. Team members do not need to track down the marketplace themselves. They just run the command Claude Code already hands them.
This settings file also keeps everyone pointed at the same marketplace and the same enabled plugins. It does not push updates on its own: a third-party marketplace like this one has auto-update off by default, so a new plugin version sits in the marketplace until someone runs the update commands (see “Versioning shared plugins” below).
Versioning shared plugins
Claude Code caches installed plugins locally in ~/.claude/plugins/cache/. If you update a skill but do not bump the version in plugin.json, users get the old behavior with no warning.
Bump the version on every change, including small ones like wording improvements. Plugin versioning follows semantic versioning: patch for typos and prompt tweaks, minor for new skills, major when behavior changes in a way that could break something that was working.
A CHANGELOG.md per plugin is easy to maintain and is the first thing to check when a skill behaves unexpectedly.
Updating takes two commands, both run from inside a Claude Code session: refreshing the marketplace catalog, then updating the plugin itself.
/plugin marketplace update
/plugin update dev-tools@acme-marketplace
Users who need to check their installed version can find it at /plugin under My Plugins.
Plugin skills as shared code
Shared code that breaks usually fails loudly: tests catch it, or the build fails. Shared skills fail silently. Claude still responds, just differently than before, with no error to surface the change. That asymmetry is why shared plugin skills need the same discipline as shared libraries: review before changes ship, a changelog, and a version bump on every release.
Getting started
Commit a .claude/skills/ directory to the project repo first. Write one skill for something your team does repeatedly. If it needs to follow people across projects, package it into a plugin. If you end up with more than one plugin, catalog them in a marketplace. If none of that happens, you have lost nothing and gained some documentation.
Skills go stale when nobody owns them. Workflows change, tools get replaced, and the skill keeps giving outdated guidance. Before you distribute shared skills, settle the question of who is responsible for keeping them accurate.
References
- Extend Claude with skills (official documentation)
- Create and distribute a plugin marketplace (official documentation)
- Codex plugins (official documentation)
- Gemini CLI extensions (official documentation)
- Agent Skills Specification