Plugin API versioned
Why it matters
Without a declared plugin API version, every host release is a potential silent breaking change for the entire plugin ecosystem. Plugins have no way to declare compatibility, so the host cannot warn before loading an incompatible plugin, and plugin authors have no signal to know which host version their code targets. ISO 25010 maintainability.modifiability requires that the impact of changes be assessable before they are made; API versioning is the mechanism that makes that assessment possible at the plugin-host boundary.
Severity rationale
High because an undeclared plugin API version prevents compatibility checking at load time, causing hook signature changes in host updates to break all installed plugins silently and without warning.
Remediation
Declare a PLUGIN_API_VERSION constant in the host and require plugins to specify their compatible version range in their manifest. Reject plugins at load time when the range is not satisfied.
// Host declares its API version:
export const PLUGIN_API_VERSION = '2.0.0';
// plugin.json:
{ "name": "my-plugin", "engines": { "host": "^2.0.0" } }
// Host checks on load:
if (!semver.satisfies(PLUGIN_API_VERSION, plugin.manifest.engines.host)) {
throw new PluginIncompatibleError(
plugin.name, plugin.manifest.engines.host, PLUGIN_API_VERSION
);
}
Detection
-
ID:
api-versioned -
Severity:
high -
What to look for: Check whether the host declares a version for its plugin API, separate from the host application version. This allows the host to ship UI changes, bug fixes, and internal refactors without incrementing the plugin API version — only changes that affect plugins trigger a plugin API version bump. Look for:
- An explicit
pluginApiVersion,extensionEngineVersion, orapiVersionfield in host configuration or manifest - A version check during plugin loading (e.g., "this plugin requires host API v2.x, current is v3.x — incompatible")
- Documentation that distinguishes "host version" from "plugin API version" Real-world examples:
- VS Code:
"engines": { "vscode": "^1.70.0" }in extension package.json - Chrome extensions:
"manifest_version": 3in manifest.json - WordPress:
Requires at least: 6.0andTested up to: 6.4in plugin headers - Minecraft:
"min_engine_version": "1.20.0"in addon manifest
- An explicit
-
Pass criteria: Count all API version identifiers. The host declares a plugin API version that plugins can check against. The version is distinct from the host application version (or the host version IS the API contract and is documented as such). Plugins can declare which API version they require.
-
Fail criteria: No plugin API version exists. Plugins have no way to declare compatibility. The host can change its plugin API at any time and plugins break silently without any version mismatch warning.
-
Skip (N/A) when: The plugin system is internal-only (all plugins live in the same repository as the host and are versioned together). Also skip for plugin systems with fewer than 2 published plugins where versioning hasn't become necessary yet.
-
Detail on fail:
"No plugin API version is declared anywhere in the host. Plugins have no way to specify which version of the host they're compatible with. When the host changes its hook signatures or removes a hook, all installed plugins break with no warning or compatibility check." -
Remediation: Plugin API versioning is the contract between host and plugin authors. Without it, every host update is a potential breaking change for the entire plugin ecosystem.
// Host declares its API version: export const PLUGIN_API_VERSION = '2.0.0'; // Plugin declares its requirement: // plugin.json: { "name": "my-plugin", "engines": { "host": "^2.0.0" } } // Host checks on load: if (!semver.satisfies(PLUGIN_API_VERSION, plugin.manifest.engines.host)) { throw new PluginIncompatibleError(plugin.name, plugin.manifest.engines.host, PLUGIN_API_VERSION); } -
Cross-reference: For backward compatibility across versions, see the
backwards-compatcheck below.
External references
- iso-25010:2011 · maintainability.modifiability — Modifiability — versioned plugin API lets the host evolve without silently breaking installed plugins
Taxons
History
- 2026-04-18·v1.0.0·Initial import from plugin-extension-architecture·automated