Plugin Development: Getting Started

StudioBrain plugins extend the application with custom UI panels, backend logic, and entity processing. Starting with the 2026-04 release, plugins are built as WebAssembly (WASM) modules that run on all platforms: web, desktop, and mobile.

Why WASM?

BenefitDetails
Cross-platformOne plugin binary runs on web (browser WASM), desktop (wasmtime), and mobile
SandboxedPlugins run in a memory-safe sandbox with no access to the host filesystem or network unless explicitly granted
FastNear-native performance for compute-heavy operations (search, analysis, transformation)
Language-agnosticWrite plugins in Rust, Python, TypeScript, C/C++, Go, or any language that compiles to WASM

Plugin Capabilities

A StudioBrain plugin can do any combination of the following:

  • Frontend panels — Custom UI rendered in the entity editor sidebar, as a tab, or as a full page
  • Backend routes — Custom REST API endpoints under /api/plugins/{plugin-id}/
  • Event handlers — React to entity lifecycle events (created, updated, deleted)
  • Settings — Global (admin) and per-user configuration
  • Data storage — Persist plugin-specific data via the Plugin Data API

Quick Start

1. Scaffold a Plugin

Use the StudioBrain CLI to scaffold a new plugin project:

npx @biloxistudios/create-plugin my-plugin
cd my-plugin

This creates a project with:

my-plugin/
  plugin.json              # Plugin manifest (required)
  src/
    lib.rs                 # WASM module entry point (Rust template)
  panels/
    main-panel.html        # Frontend panel
  Cargo.toml               # Rust build config
  README.md

Templates are available for Rust, Python (via componentize-py), and TypeScript (via javy).

2. Define the Manifest

Edit plugin.json to declare your plugin’s capabilities:

{
  "id": "my-plugin",
  "name": "My Plugin",
  "version": "1.0.0",
  "description": "A custom StudioBrain plugin",
  "author": "Your Name",
  "license": "MIT",
  "icon": "Puzzle",
  "wasm": {
    "module": "target/wasm32-wasi/release/my_plugin.wasm"
  },
  "capabilities": {
    "frontend": {
      "panels": [
        {
          "id": "main-panel",
          "title": "My Panel",
          "location": "entity-sidebar",
          "url": "/panels/main-panel.html"
        }
      ]
    },
    "host_functions": [
      "entity_read",
      "entity_list",
      "storage_get",
      "storage_set"
    ],
    "settings": {
      "global": [
        {
          "key": "api_key",
          "label": "External API Key",
          "type": "password",
          "default": ""
        }
      ]
    }
  }
}

3. Implement the WASM Module

For a Rust plugin:

// src/lib.rs
use studiobrain_plugin_sdk::*;
 
#[export]
fn on_entity_created(entity: Entity) -> Result<(), PluginError> {
    let entity_type = entity.entity_type();
    let entity_id = entity.id();
 
    // Call a host function to read related entities
    let related = host::entity_list(&format!(
        "entity_type=character&related_to={}", entity_id
    ))?;
 
    // Process and store results
    host::storage_set(
        &format!("analysis/{}", entity_id),
        &serde_json::to_string(&related)?
    )?;
 
    Ok(())
}
 
#[export]
fn on_entity_updated(entity: Entity) -> Result<(), PluginError> {
    // Re-run analysis on update
    on_entity_created(entity)
}

4. Build

# Rust
cargo build --target wasm32-wasi --release
 
# Python (via componentize-py)
componentize-py -d plugin.wit -w plugin componentize my_plugin -o my_plugin.wasm
 
# TypeScript (via javy)
javy compile src/index.js -o my_plugin.wasm

5. Install

Copy the plugin directory to _Plugins/my-plugin/ in your StudioBrain project, or upload via the Plugin Marketplace UI in Settings.

Host Functions Reference

WASM plugins interact with StudioBrain through host functions — APIs that the host runtime makes available to the sandboxed module. Plugins declare which host functions they need in plugin.json under capabilities.host_functions.

Host FunctionDescriptionParameters
entity_readRead a single entity by ID(entity_type: string, entity_id: string) -> Entity
entity_listList entities with optional filters(query: string) -> Entity[]
entity_createCreate a new entity(entity_type: string, data: string) -> Entity
entity_updateUpdate an existing entity(entity_type: string, entity_id: string, data: string) -> Entity
entity_deleteDelete an entity(entity_type: string, entity_id: string) -> bool
storage_getRead plugin-scoped data(key: string) -> string
storage_setWrite plugin-scoped data(key: string, value: string) -> bool
storage_deleteDelete plugin-scoped data(key: string) -> bool
storage_listList keys in plugin storage(prefix: string) -> string[]
setting_getRead a plugin setting value(key: string) -> string
logWrite to the plugin log(level: string, message: string) -> void
http_requestMake an outbound HTTP request (if permitted)(method: string, url: string, body: string) -> Response

Permission Model

Plugins only have access to the host functions they declare. Undeclared functions return an error at runtime. The http_request function requires explicit user approval during plugin installation.

Frontend Panels

Plugin frontend panels are HTML/CSS/JS files served in sandboxed iframes. They communicate with the host app via the postMessage protocol.

Iframe Protocol

The host sends these messages to the plugin iframe:

Message TypeWhenData
entity-contextOn iframe loadEntity type, ID, data, theme
entity-updatedWhen entity data changesUpdated entity data
theme-changeWhen user toggles light/darkCurrent theme

The plugin can send these messages to the host:

Message TypePurposeData
entity-modifiedRequest field updatesChanged fields
navigateNavigate host to a routePath
toastShow notificationMessage + level
resizeResize iframe containerHeight in pixels

See Plugin Iframe Protocol for full type definitions and examples.

Theme Compliance

Plugins must use CSS custom properties for colors, not hardcoded values. StudioBrain injects the current theme (light/dark) via the entity-context message. See Plugin Development for the surface variable reference.

SDK Templates

Starter templates are available for the three most common plugin languages:

LanguageTemplateBuild Tool
Rustnpx @biloxistudios/create-plugin --template rustcargo build --target wasm32-wasi
Pythonnpx @biloxistudios/create-plugin --template pythoncomponentize-py
TypeScriptnpx @biloxistudios/create-plugin --template typescriptjavy compile

Each template includes a working plugin.json, a minimal WASM module, a frontend panel, and a build script.

Next Steps