Skip to main content

Plugin dependencies and inter-plugin calls

A plugin can depend on other plugins (prerequisite plugins) and call methods across plugins. A typical case: MarkdownLib is a library plugin that provides a renderMarkdown method, and other plugins depend on it and call it from their pages.

1. Declare dependencies

Declare them in the dependencies field of the manifest:

2. Required dependency (optional: false)

  • On install: if the plugin is missing or its version does not satisfy the range, installation is refused and the backend returns PLUGIN_MISSING_DEPENDENCY(400); the error message lists the missing items.
  • On startup: if the prerequisite plugin is not installed or not enabled, this plugin skips activation and is set to disabled.
  • Users must install the prerequisite plugin before they can install plugins that depend on it.

3. Optional dependency (optional: true)

  • Installation and activation are not strictly checked.
  • callPlugin can call its methods only when the prerequisite exists and is enabled.
  • When the prerequisite is missing, callPlugin errors but the plugin itself is still enabled normally.
  • Always wrap calls to optional dependency methods in try/catch:

4. Library plugin conventions (the provider)

Library plugins (such as MarkdownLib) typically:
  • Do not declare contributes.menuItems → no entry is created in the sidebar.
  • Declare only entry.frontend (even a blank page) plus registerMethod on activation.
  • Include at least config:write in permissions (required by registerMethod).
A library plugin’s layers can be pure ["l3"] (inline) or ["l2", "l3"] (sandbox). Key points:
  • Activation depends on whether entry.frontend exists plus whether the user enabled the plugin; it is unrelated to layers.
  • entry.frontend is mandatory: only plugins that declare a frontend are activated (and thus run scripts and register methods). A plugin without a frontend is never activated, so its methods are never registered.
See layers.

5. Provider: register methods

The depended-on plugin registers methods in its page script after activation:
  • registerMethod(method, fn): fn returns a value or a Promise (async methods are supported too).
  • One plugin can register multiple methods.
  • All methods are unregistered automatically when the plugin is disabled.
  • Permission: config:write.

6. Consumer: call methods

  • Call signature: callPlugin(插件Id, 方法名, ...参数)
  • Permission: network:fetch
  • Async methods are supported (await directly when the provider returns a Promise).

7. Activation order

On startup the launcher activates depended-on plugins first (topological sort via sortByDependencies), so prerequisites are ready and have registered their methods by the time dependents activate. You do not need to care about declaration order in the manifest.

8. Error handling

Full flow

  • The user installs MarkdownLib → succeeds (no dependencies).
  • The user installs the AI assistant → the backend checks dependencies: markdown is installed and 1.2.0 >= 1.0.0 → succeeds.
  • The launcher starts → activates MarkdownLib first (registers renderMarkdown) → then activates the AI assistant.
  • The AI assistant calls callPlugin('top.qomicex.markdown', 'renderMarkdown', md) → the main window relays it through __pluginRegistry → the rendered result is returned.