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.
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.
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
);
}
ID: plugin-extension-architecture.versioning-contracts.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:
pluginApiVersion, extensionEngineVersion, or apiVersion field in host configuration or manifest"engines": { "vscode": "^1.70.0" } in extension package.json"manifest_version": 3 in manifest.jsonRequires at least: 6.0 and Tested up to: 6.4 in plugin headers"min_engine_version": "1.20.0" in addon manifestPass 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-compat check below.