Skip to Content

Plugins

A plugin is a package — a plugin.json manifest plus an ES module — installed from a .zip or a folder.

Installing

Window → Plugins… opens the manager. Choose a .zip or a folder.

Before any code exists anywhere, the manifest is validated and a consent screen shows you what the plugin is asking to be allowed to do. Only after you accept does the entry module get loaded.

Installing registers the plugin’s commands immediately — no restart — and they appear in the command palette and the Plugins menu right away. Installs persist across reloads.

Permissions

PermissionThe plugin can
scene:readSee layer names, structure and scalar properties
scene:writeCreate, change and delete layers
animation:readRead keyframes and sample animated values
animation:writeCreate and change keyframes and expressions
timelineRead the current time and move the playhead

Registering commands, showing notifications, opening the plugin’s own panel and reading composition settings need no permission — none of those read project data or change it.

Consent is per permission, not one yes over the list. The install screen ticks everything the manifest asks for and you may untick any of it. You can change your mind later — Manage Plugins… → Permissions on the row — which restarts the plugin with the new set. A grant is always intersected with the manifest, so nothing can end up with more than it disclosed.

A refused call returns an error naming the missing permission rather than silently doing nothing, so a well-written plugin degrades deliberately instead of behaving strangely.

Why this is safe

Each plugin runs in a Worker sandbox that locks down its own globals before importing the plugin’s code.

Failure modeWhat actually happens
Plugin loops foreverThe worker stops answering a heartbeat and is terminated in about 12 seconds. The editor is untouched
Plugin tries to read your account token or AI keysThere is no localStorage in a worker realm
Plugin tries to phone homefetch, XMLHttpRequest, WebSocket and importScripts are replaced with throwing stubs before the plugin’s module is imported
Plugin tries to read the interface or forge clicksNo document, no window
Plugin deletes your projectIt needs scene:write, and it is one Ctrl/ + Z

Every host API call executes inside the command system, so anything a plugin changes is a single undo.

Panels

A plugin’s UI panel runs in a frame sandboxed without same-origin access, so it has an opaque origin and cannot read the editor’s document, cookies or storage. Its only way out is a message to its own plugin — not to the editor, and not to another plugin.

Panels have no network: inline scripts run, fetch does not, and a remote image is refused.

This design exists because downloading plugins from strangers is the normal distribution model for creative tools. “The user chose the file” is not a security control.

Supervision

MechanismBehaviour
Boot timeout8 seconds to activate, then stopped with a reason
HeartbeatPinged every 4 seconds; two unanswered pings terminate it
ErrorsSurfaced, never swallowed — a fatal shows in the manager row with a Restart button, and as a toast prefixed with the plugin’s name
LogPer plugin. Carries its own console output, every call the permission gate refused, and the crash that stopped it. Kept after the plugin dies, because that is when it gets read

A plugin that is installed but not running still appears in the menu, disabled, saying why. Nothing an installed plugin does is invisible.

Where a plugin shows up

ContributionWhere you find it
Registered commandsThe Plugins menu under the plugin’s name, and the command palette
A panelThe Plugins dock panel, tabbing alongside Effects and Graph
NotificationsToasts, always prefixed with the plugin’s name
The packagePlugins → Manage Plugins… — status, permissions, enable/disable, uninstall
Last updated on