Appearance
Plugins
Bubbledesk’s Plugins provides a secure, sandboxed and flexible runtime for executing WebAssembly (WASM) plugins within the desktop wrapper.
This allows developers to extend app capabilities and Bubbledesk to release features without forcing new builds.
Overview
Each worker runs in its own hidden webview window (bd-worker) and executes WASM modules inside a Web Worker environment. The runtime isolates every execution, providing:
- File system sandboxing
- Automatic timeout and queue limits
- JSON-based communication
- Cross-platform consistency (macOS, Windows, Linux)
BRIDGE
Workers are managed via the JavaScript bridge at Bubbledesk.worker.
You can find the documentation for the worker module here.
Architecture
The system is composed of three layers:
| Layer | Language | Responsibility |
|---|---|---|
| Frontend | JavaScript or TypeScript | Provides the API under Bubbledesk.worker |
| Backend Host | Rust + Tauri | Manages worker lifecycle, WASM validation, job queueing, and communication |
| Execution Layer (Web Worker) | JavaScript + WASM | Executes the loaded WebAssembly module and streams stdout/stderr |
All communication between host and worker is event-driven via the Tauri IPC system.
Input/Output Standard
The communication protocol is line-delimited JSON:
Input (from host → plugin)
The Bubbledesk sandbox passes JSON via stdin.
Example:
json
{ "fn": "add", "args": [3, 5] }Output (from plugin → host)
The plugin must write a single line of JSON to stdout, terminated by \n.
Example:
Success:
json
{"ok": true, "value": 8}Error:
json
{"ok": false, "error": "division by zero"}This format is mandatory — the worker will reject malformed or multiline JSON.
Security and Sandbox
- Each plugin executes in its own isolated environment.
Each job runs in a sandboxed folder (
/_sandbox/<jobId>), mapped as/inside the module. Here (and here only) you can read/write files with the plugin. - No network access or external FS access is allowed.
- Max 64 concurrent pending jobs.
- Input limited to 1 MB per call.
- WASM modules must start with the standard
\0asmmagic bytes.
WASM Plugin Structure
Each plugin is an independent Rust project compiled for the wasm32-wasip1 target and executed as a WASI-compatible process.
Example structure:
math/
├─dist/
| └─ math.wasm
├─ src/
│ ├─ main.rs
│ ├─ dispatcher.rs
│ └─ functions.rs
├─ Cargo.toml
└─ package.jsonPlugins communicate with the host via stdin/stdout, using a strict JSON protocol.
Requirements
Build
Each module is built into .wasm with:
bash
npm run build -- <moduleDirName>Example:
bash
npm run build -- mathResult in dist/ folder, example:
dist/math.wasmDirectory Layout
| Directory | Purpose |
|---|---|
/_external_modules/ | Holds installed WASM modules |
/_sandbox/<jobId> | Temporary runtime area, wiped at startup |
Develop a Plugin
Fork the
bd-wasm-module-templaterepo from Bubbledesk's GitHub:urlhttps://github.com/Bubbledesk/bd-wasm-module-templateCopy the
module-templatefolder with a new name:bashcp -r module-template my-new-moduleEdit
Cargo.tomlwith the module name and description.Implement your functions in
functions.rsand register them indispatcher.rs.Build:
bashnpm run build -- my-new-moduleYou can load
dist/my-new-module.wasminto your Bubbledesk app with:tsawait Bubbledesk.worker.modules.add("moduleName");then select
dist/my-new-module.wasm.You can list loaded modules with:
tsawait Bubbledesk.worker.modules.list();You can call it like this:
jsconst res = await Bubbledesk.worker.call("moduleName.wasm", { fn: "function_name", args: [...] }); console.log(JSON.parse(res).value);
Keywords References
- Plugin = WASM Module
- Worker = Isolated runtime where the plugins run
- WASM = WebAssembly
WebAssembly (WASM)
WebAssembly (WASM) is a portable binary format that enables high-performance code — written in languages (like Rust, C, or C++) — to run safely inside browsers or sandboxed runtimes such as Tauri + browser web worker.
Notes
BRIDGE
Workers are managed via the JavaScript bridge at Bubbledesk.worker.
You can find the documentation for the worker module here.
NOTES
- Keep functions pure and deterministic, without external side effects.
- Do not use network: it is blocked by the sandbox.
- Avoid extra stdout/stderr: only the final JSON output should be printed.
- All modules must follow the stdin/stdout JSON protocol strictly. Multi-line, non-JSON, or binary outputs will be discarded.
WARNING
Avoid infinite loops or blocking operations inside your WASM module — they will trigger a timeout and the worker will be restarted.