How Plugin Dependencies and Version Constraints Work in Claude Code Plugins
Claude Code plugins use semantic versioning declared in .claude-plugin/plugin.json to enforce compatibility, while individual commands specify minimum required versions in front-matter blocks that the runtime validates before execution.
The anthropics/claude-plugins-official repository implements a self-contained plugin architecture where dependencies and version constraints are managed through declarative metadata rather than traditional package managers. Each plugin carries its own version identity, and commands declare exactly which plugin versions they support, enabling the runtime to prevent incompatible executions.
Declaring Plugin Versions in plugin.json
Every Claude Code plugin must include a .claude-plugin/plugin.json file that serves as the source of truth for the plugin's identity and version.
The Core Version Fields
The plugin.json file requires two critical fields for dependency management:
name– A unique identifier for the plugin across the ecosystem.version– A semantic version string (e.g.,1.2.3) that follows strict semver rules.
The runtime extracts the version using standard JSON parsing tools. For example, the plugins/skill-creator/.claude-plugin/plugin.json demonstrates this pattern with a clear version declaration that the marketplace and CLI tools reference during installation and updates.
Command-Level Version Constraints
Individual commands within a plugin can require specific minimum versions when they depend on features introduced in newer releases.
Minimum Version Declarations in Front-Matter
Command authors declare version constraints inside the command's markdown file using a standardized front-matter block. According to plugins/plugin-dev/skills/command-development/references/marketplace-considerations.md, the canonical syntax appears as:
---
description: Version-aware command
---
<!--
COMMAND VERSION: 2.1.0
COMPATIBILITY:
- Requires plugin version: >= 2.0.0
-->
The .claude-plugin/marketplace.schema.json validates that this block is present for marketplace-published commands, ensuring that version requirements are explicit before distribution.
Runtime Enforcement of Version Constraints
Claude Code automatically extracts the installed plugin version and compares it against the command's declared constraints before executing any logic.
Semantic Version Comparison Logic
The runtime performs version checks using standard shell tools. As documented in plugins/plugin-dev/skills/command-development/references/marketplace-considerations.md, a typical validation script looks like:
# Detect plugin version
PLUGIN_VERSION=$(jq -r .version .claude-plugin/plugin.json)
# Enforce minimum version using sort -V for semantic comparison
REQUIRED="2.0.0"
if [[ "$(printf '%s\n' "$REQUIRED" "$PLUGIN_VERSION" | sort -V | head -n1)" != "$REQUIRED" ]]; then
echo "❌ ERROR: $PLUGIN_NAME version $PLUGIN_VERSION < required $REQUIRED"
echo "Run '/plugin update $PLUGIN_NAME' to upgrade."
exit 1
fi
echo "✓ Plugin version $PLUGIN_VERSION satisfies >= 2.0.0"
This comparison follows semantic versioning rules, where the marketplace tooling normalizes version strings before evaluation. When the strict field is set to true in marketplace.json, the runtime enforces exact version matches rather than minimum thresholds.
External Tool Dependencies
Beyond the plugin's own version, commands often require external binaries such as Git, jq, Node.js, or Docker. These dependencies are declared separately from the plugin version constraints.
Required and Optional Tool Declarations
Commands list external dependencies in a fenced comment block within the markdown file. The convention, as shown in plugins/plugin-dev/skills/command-development/references/marketplace-considerations.md, uses this structure:
<!--
DEPENDENCIES:
Required:
- git # version ≥ 2.0
- jq # version ≥ 1.6
Optional:
- gh # GitHub CLI – adds PR shortcuts
- docker # Enables containerised tests
-->
Runtime Tool Validation
At execution time, a helper script validates these dependencies using command -v checks. Required tools cause immediate aborts with clear error messages if missing, while optional tools enable graceful degradation:
declare -A REQ_DEPS=( ["git"]="2.0" ["jq"]="1.6" )
for tool in "${!REQ_DEPS[@]}"; do
if ! command -v "$tool" >/dev/null; then
echo "❌ Missing required tool: $tool (version ${REQ_DEPS[$tool]} or higher required)"
exit 1
fi
done
echo "✓ All required tools are present"
The plugins/hookify/README.md demonstrates how hook plugins can declare optional dependencies, such as node_modules for analysis, allowing the command to skip advanced features when tools are unavailable.
Plugin Self-Containment and Bundling
Unlike traditional package managers, Claude Code plugins do not declare external library dependencies in plugin.json. The architecture requires all code to be bundled inside the plugin directory.
When a plugin requires third-party libraries (such as Python's requests package), the author includes the library source under the plugin folder and references it via relative imports. The marketplace does not enforce a dependencies field because the execution environment is controlled by Claude Code itself. This design ensures plugins remain portable and do not conflict with system-wide package installations.
Updating Plugins and Constraint Re-evaluation
When publishers release new plugin versions, the update flow triggers automatic re-validation of all version constraints.
Users execute /plugin update <plugin-name> to fetch the latest plugin.json and replace the plugin folder. On the next command invocation, the runtime re-evaluates any version constraints. If a command's requirement is no longer satisfied—such as after an accidental downgrade—the same version-check logic produces a diagnostic error pointing the user back to /plugin update.
Summary
- Version strings are authoritative – Every plugin must declare a
versionfield in.claude-plugin/plugin.jsonusing semantic versioning. - Commands declare minimum versions – Front-matter blocks in command markdown files specify the lowest compatible plugin version using the
COMPATIBILITYsyntax. - Runtime enforces constraints – Before execution, the platform compares installed versions against requirements using semantic version comparison logic.
- External tools are validated separately – Required and optional binaries are listed in
DEPENDENCIES:blocks and checked at runtime withcommand -v. - Plugins must be self-contained – No external library dependencies are declared in
plugin.json; all required code must live inside the plugin directory.
Frequently Asked Questions
Where do I declare the minimum plugin version for a command?
You declare the minimum version inside the command's markdown file using a front-matter comment block. Place a COMPATIBILITY section under the command header that specifies Requires plugin version: >= X.Y.Z. The .claude-plugin/marketplace.schema.json validates this block for marketplace submissions.
How does Claude Code validate external tool dependencies?
The runtime executes a validation script that loops through the DEPENDENCIES: list in the command's front-matter. It uses command -v to verify that required binaries exist in the system PATH. If a required tool is missing, the command aborts with an error message; if an optional tool is missing, the command executes with degraded functionality.
What happens if a plugin version is incompatible with a command?
When a command's declared minimum version exceeds the installed plugin version, the runtime prints an error message indicating the version mismatch and suggests running /plugin update <plugin-name>. The command exits with a non-zero status before executing any logic, preventing incompatible operations.
Can plugins declare external library dependencies in plugin.json?
No. The plugin.json file does not support a dependencies array for external libraries. Claude Code plugins must bundle all required code within the plugin directory itself. If you need third-party libraries, include them as vendored dependencies and reference them using relative imports.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →