[FEATURE] Support for Plugin Dependencies and Shared Resources
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Summary
Add support for plugin dependencies and shared resource libraries to the Claude Code plugin system, enabling plugins to declare dependencies on other plugins or common libraries.
Motivation
Current Limitation
Today, plugins are completely independent units. If multiple plugins need the same agents, hooks, or utilities, each plugin must duplicate these resources. This leads to:
- File duplication - Same agent definitions copied across multiple plugins
- Maintenance burden - Updates must be applied to all copies
- Inconsistency risk - Copies can drift out of sync
- Storage waste - duplicated agents in the marketplace
Real-World Example
Our marketplace has 11 plugins. We had to copy 32 agents across 7 plugins because:
@code-archaeologistis used by: epcc-workflow, documentation, architecture, tdd-workflow, performance@security-revieweris used by: epcc-workflow, architecture, tdd-workflow, security@test-generatoris used by: epcc-workflow, documentation, architecture, tdd-workflow, testing
Without dependencies: Copy 32 agents = duplication With dependencies: 1 common-core plugin = no duplication Pros: Simple, no changes needed Cons: Maintenance burden, inconsistency risk Verdict: ❌ Not scalable as marketplace grows
2. Documentation-Only Dependencies
Tell users "install common-core first" Pros: No code changes Cons: ❌ Not enforced, easy to miss, poor UX Verdict: ❌ Unreliable
3. Monolithic Plugins
Make each plugin completely self-contained Pros: Always works Cons: ❌ Massive duplication (current solution) Verdict: ✅ Good short-term, ❌ bad long-term
Related Issues
- Plugin system scalability
- Marketplace organization
- Plugin development experience
Proposed Solution
Proposed Solution
1. Plugin Dependencies in Manifest
Add dependencies field to plugin.json:
{
"name": "epcc-workflow",
"version": "1.0.0",
"dependencies": {
"common-core": "^1.0.0",
"security-core": "^2.1.0"
},
"agents": ["agents/"],
"commands": ["commands/"]
}
2. Common Resource Plugins
Allow plugins to declare themselves as libraries:
{
"name": "common-core",
"version": "1.0.0",
"type": "library",
"description": "Common agents used across multiple plugins",
"agents": ["agents/"],
"exports": {
"agents": [
"code-archaeologist",
"system-designer",
"business-analyst"
]
}
}
3. Automatic Dependency Resolution
When installing a plugin:
/plugin install epcc-workflow@claude-code-plugins
# Claude Code automatically:
✓ Resolving dependencies...
✓ Installing [email protected]
✓ Installing [email protected]
✓ Installing [email protected]
✓ All dependencies satisfied
4. Shared Resource Directory Structure
~/.claude/plugins/
├── [email protected]/
│ ├── commands/
│ └── .claude-plugin/plugin.json # declares dependencies
├── [email protected]/
│ ├── agents/
│ │ ├── code-archaeologist.md
│ │ └── system-designer.md
│ └── .claude-plugin/plugin.json # type: "library"
Plugins can reference shared agents:
# From epcc-workflow commands
@code-archaeologist # Resolves from common-core dependency
Benefits
For Plugin Authors
- ✅ DRY principle - Define agents once, reuse everywhere
- ✅ Easier maintenance - Update one file, all plugins benefit
- ✅ Smaller plugins - Plugins only contain unique resources
- ✅ Clear dependencies - Explicit dependency graph
For Users
- ✅ Automatic installation - Dependencies installed transparently
- ✅ Faster installs - Shared resources downloaded once
- ✅ Consistency - Same agent version across all plugins
- ✅ Better reliability - Fewer missing dependency errors
For Marketplace
- ✅ Scalability - More plugins without N² duplication
- ✅ Quality - Centralized, well-tested common resources
- ✅ Organization - Clear separation of concerns
Design Considerations
Dependency Resolution
- Semver support -
"^1.0.0","~2.1.0",">=1.5.0" - Circular dependency detection - Fail with clear error
- Version conflicts - Choose highest compatible version
- Peer dependencies - Optional for flexibility
Performance
- Lazy loading - Only load dependencies when needed
- Caching - Shared resources cached for speed
- Parallel installs - Install dependencies concurrently
Backwards Compatibility
- Optional feature - Plugins without dependencies still work
- Graceful degradation - Fall back to bundled resources if dependency unavailable
- Migration path - Clear documentation for converting existing plugins
Alternative Solutions
Alternative Approaches Considered
1. Continue with Duplication (Current)
Pros: Simple, no changes needed Cons: Maintenance burden, inconsistency risk Verdict: ❌ Not scalable as marketplace grows
2. Documentation-Only Dependencies
Tell users "install common-core first" Pros: No code changes Cons: ❌ Not enforced, easy to miss, poor UX Verdict: ❌ Unreliable
3. Monolithic Plugins
Make each plugin completely self-contained Pros: Always works Cons: ❌ Massive duplication (current solution) Verdict: ✅ Good short-term, ❌ bad long-term
Related Issues
- Plugin system scalability
- Marketplace organization
- Plugin development experience
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
Real-World Example:
[AWS Advanced Agent Patterns] (https://github.com/aws-samples/anthropic-on-aws/tree/main/advanced-claude-code-patterns)
Our proposed marketplace has 11 plugins. We had to copy 32 agents across 7 plugins because:
@code-archaeologistis used by: epcc-workflow, documentation, architecture, tdd-workflow, performance@security-revieweris used by: epcc-workflow, architecture, tdd-workflow, security@test-generatoris used by: epcc-workflow, documentation, architecture, tdd-workflow, testing
Without dependencies: Copy 32 agents = duplication With dependencies: 1 common-core plugin = no duplication Pros: Simple, no changes needed Cons: Maintenance burden, inconsistency risk Verdict: ❌ Not scalable as marketplace grows
2. Documentation-Only Dependencies
Tell users "install common-core first" Pros: No code changes Cons: ❌ Not enforced, easy to miss, poor UX Verdict: ❌ Unreliable
3. Monolithic Plugins
Make each plugin completely self-contained Pros: Always works Cons: ❌ Massive duplication (current solution) Verdict: ✅ Good short-term, ❌ bad long-term
Examples from Other Systems
NPM/Node.js
{
"dependencies": {
"lodash": "^4.17.21"
},
"peerDependencies": {
"react": ">=16.0.0"
}
}
Python pip
install_requires=[
'requests>=2.25.0',
'numpy~=1.20.0'
]
VSCode Extensions
{
"extensionDependencies": [
"ms-python.python"
]
}
Additional Context
References
they already sollved this you can have the resources in the market place root, and then use strict: false, and then the plugin config in the market place can define more granular assignments of command/agents/hooks
they already sollved this you can have the resources in the market place root, and then use strict: false, and then the plugin config in the market place can define more granular assignments of command/agents/hooks
I would argue this is a work around, not a solution. In my opinion the solution would use the same @ reference already implemented but be context aware of the marketplace.
they already sollved this you can have the resources in the market place root, and then use strict: false, and then the plugin config in the market place can define more granular assignments of command/agents/hooks
I tested this and, unless I am missing something, You cannot reference things at the market place root from a plugin due to the schema requirement that the plugin paths start with ./. see error below.
/plugin ⎿ Failed to load all marketplaces. Errors: test-marketplace: Invalid schema: plugins.0.skills.0: Invalid input: must start with "./",
"plugins": [
{
"name": "test",
"source": "./plugins/test",
"description": "test",
"strict": false,
"commands": [
"./hello.md"
],
"skills": [
"../dep.md"
]
},
Edit: I figured out how to reference, it requires raising the source path. It does not work with @ reference but does work with "use skill X". Still feels like a workaround, its not awesome.
thank you @jawhnycooke...I was just about to file a feature request before I found yours
Regarding the dependencies block
The current structure:
"dependencies": {
"common-core": "^1.0.0",
"security-core": "^2.1.0"
}
While this follows the familiar npm/PyPI pattern, it assumes a single centralized marketplace. To support multiple Claude Code Marketplaces/Plugins, including private/internal registries, I'd suggest a more flexible structure:
"dependencies": [
{
"name": "my-plugin",
"version": "1.0.0",
"source": "./plugins/my-plugin"
},
{
"name": "my-other-plugin",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://gitlab.com/team/my-other-plugin.git"
}
},
]
This approach would:
- Support local file paths for development/internal plugins
- Enable git repositories as dependency sources
- Allow custom registries/marketplaces
This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.
Building on what @smar-sean-sekora suggests, I might also add that local referenced plugins should probably not have a version. I'd probably consider the reference similar to github actions, where references to remote repos can use a tag or sha or branch.
I'd forsee some basic issues here though: when you have dependencies, how do you ensure those dependencies do their thing before you need to (eg hook ordering).
One thing that made me think about this was the potential for a plugin that contains a bunch of supporting rules, and an mcp server that syncs those rules in to the .claude folder for an org to use to sync rules. (the mcp server doesn't do anything, it just uses the execution to kick off the syncing process and potentially watch for updates on long running sessions)
To this end, I wanted to make a plugin that handled the basic ideas of the syncing and mcp server with no rules, and another plugin that depended on that other plugin to sync it's rules.
To help mitigate issues, perhaps plugins should opt in to being used as a dependency by stating in their schema that they take inputs, which then lets the depend-er define the dependency and then pass it's own info to the other plugin.
As I type this, while "dependencies" feels like the right term, the actuality is that this feels a bit more like github actions. Having the following as the schema would enact the above ideas:
"dependencies": [
{
"uses": "./plugins/rule-sync"
"with": {
"ruleRoot": "./rules" // relative to this plugin
}
},
{
"uses": "https://gitlab.com/team/[email protected]"
},
{
"uses": "https://gitlab.com/team/my-other-plugin.git/subpath/to/[email protected]" // where the .claude-plugin folder lives
},
{
"uses": "githuborg/github-repo" // default to sourcing from github, and from default branch
},
]
The update to the schema for the plugins that can be depended on could look like:
"depdenencies": [
{
// if this were to be installed rather than depended on, this is where it would define it's inputs
// If a plugin defines a reusable block, but doesn't depend on itself, then it doesn't do anything!
// This ensures plugin use is intentional and won't break due to some things being missing.
// Probably better to encourage an in-tree plugin that uses the reusable one instead of the
// reusable one depending on itself?
"uses": "./"
}
]
"resusable": { // presence indicates you can `use` it in another one
"inputs": {
"rulesRoot": {
"type": "path", // so strings are mapped relative to the plugin that sent the input
"required": true, // if the value isn't passed, this plugin fails to load and claude reports an error
"default": "./rules", // the value (relative to the USING plugin) to use if not provided
"mcp": { // use this value in MCP configs
"env": { // by setting an env var to expose it
"RULES_ROOT_DIR": "${{ .value }}"
}
},
"hooks": { /* ... */ }, // same as mcp, but expose for hooks
"env": { // or set globally for things used within this plugin
"RULES_ROOT_DIR": "${{ .value }}"
}
}
}
}
they already sollved this you can have the resources in the market place root, and then use strict: false, and then the plugin config in the market place can define more granular assignments of command/agents/hooks
I tested this and, unless I am missing something, You cannot reference things at the market place root from a plugin due to the schema requirement that the plugin paths start with ./. see error below.
/plugin ⎿ Failed to load all marketplaces. Errors: test-marketplace: Invalid schema: plugins.0.skills.0: Invalid input: must start with "./",
"plugins": [ { "name": "test", "source": "./plugins/test", "description": "test", "strict": false, "commands": [ "./hello.md" ], "skills": [ "../dep.md" ] },Edit: I figured out how to reference, it requires raising the source path. It does not work with @ reference but does work with "use skill X". Still feels like a workaround, its not awesome.
What if we use a git submodule placed inside the your own plugin folder, then it would look something like:
"plugins": [
{
"name": "test",
"source": "./plugins/test",
"description": "test",
"strict": false,
"commands": [
"./hello.md"
],
"skills": [
"./{submodulename}/dep.md"
]
},
Then, for updating it is not hard to set an action that auto-update submodules.
Did someone tried a workaround like this? Would that work?