Skip to content
EN

How the Plugin System works

Last updated

Plugins in Visualizer do not run as a single piece of code. Instead, each Plugin is split into two parts that run in separate environments and communicate with each other. This architecture determines what your code can and cannot do depending on where it runs.

When a Plugin loads, Visualizer runs its code in two environments:

  • A WebAssembly environment, which has direct access to Visualizer data and the Plugin API.
  • An iframe environment, which handles all UI rendering and has access to standard browser APIs.

Neither environment can do everything on its own. WebAssembly can read and interact with Visualizer data but cannot render HTML or call most browser APIs. The iframe can render HTML and call browser APIs but cannot access Visualizer data directly. Together, they complement each other.

The two sides communicate using postMessage, a standard browser mechanism for safe communication between separate execution contexts. When the UI needs data from Visualizer, it requests the data from the WebAssembly side, which fetches it and sends it across.

The WebAssembly side is the Plugin’s entry point. This is the first code that runs when a Plugin loads, and it runs synchronously in the same thread as Visualizer.

What you can do:

  • Access scene data from Visualizer.
  • Call the Plugin API.
  • Partially update the Visualizer scene, such as changing layer properties.
  • Subscribe to events from the scene.
  • Send data to and receive data from the iframe side via postMessage.

What you cannot do:

  • Render HTML or any UI directly; this must be handled on the iframe side.
  • Use most browser APIs; a limited set is available, such as console.log.
  • Make HTTP requests to external servers.

The iframe side handles everything visual in your Plugin. It behaves like a standard web page and has access to browser APIs.

What you can do:

  • Render HTML as you would in a normal web page.
  • Use browser APIs, including DOM APIs, Canvas, and fetch.
  • Make HTTP requests to external servers when the server includes Access-Control-Allow-Origin: * in its response headers.
  • Send data to and receive data from the WebAssembly side via postMessage.

What you cannot do:

  • Access or change Visualizer data directly; request it from the WebAssembly side via postMessage.
  • Communicate with the Visualizer back end directly.
  • Make HTTP requests to servers that do not include Access-Control-Allow-Origin: * in their response headers because the iframe is sandboxed with a null origin.
  • Use local storage for the same sandboxing reason.
  • Use browser APIs that require explicit permission from the parent page. For example, the Clipboard API is not available by default in the sandboxed iframe.
CapabilityWebAssembly sideiframe side
Sandboxed
Entry point (runs first)
Access to Plugin API
Render HTML
Use browser APIs
Communicate via postMessage

postMessage serialization: postMessage can only send data that can be serialized as JSON. Objects such as ArrayBuffer and Blob cannot be sent directly. Encode binary data as a base64 string before transferring it.

Plugin size: Plugins must be packaged as .zip files of 10 MB or less.

Static assets: Non-JavaScript files such as images, HTML, and CSS cannot be packaged inside a Plugin. Embed them in JavaScript as strings, or host them on a publicly accessible server and reference them by URL.

Local storage: Local storage is unavailable on both sides. To persist data, use the storage API provided by the Plugin API or an external server.