Plugin Loaders¶
A plugin's surface (see Plugin concepts) is what it does — a scalar function, an aggregate, a procedure. A loader is the other axis: it determines how that surface is authored, what language it is written in, how it is built, and whether it runs trusted in-process or inside a sandbox. The execution layer is loader-agnostic — a registered scalar looks identical to the query engine no matter which loader produced it — so the same surface can be delivered by any of the five loaders below.
Uni ships five loaders: Rust (native), WASM Component Model, Extism, Rhai, and PyO3. They split into two trust postures: Rust and PyO3 run trusted, in-process; WASM Component Model, Extism, and Rhai run sandboxed. The same logic produces byte-identical output across the two WASM ABIs (verified by the cross-ABI parity test), and matches to within 4 ULP for Rhai and PyO3.
Choosing a loader¶
Pick by trust, language, and how the plugin is delivered:
- First-party extension, all surfaces, full speed → Rust. The native loader is the only one that can author all 23 extension surfaces (CRDTs, indexes, storage backends, hooks, triggers, and more — not just scalar/aggregate/procedure). It runs trusted in-process at native speed and is the path every built-in uses. Choose it when you control the code and are packaging it into the host. Loaded via
add_plugin, which is trust-enforced. - Sandboxed polyglot binary → WASM Component Model (preferred) or Extism. Both run untrusted third-party code in a wasmtime sandbox and are loadable from any host language, including Python. Prefer WASM Component Model when you want a typed contract: it uses typed WIT worlds, so argument and return shapes are checked at the ABI boundary. Choose Extism for a simpler host-function ABI, which links only the host functions for granted capabilities.
- Lightweight scripting → Rhai. A sandboxed, pure-Rust scripting engine with no separate build step — author a script and load it. Good for small ops-style logic. Loadable from Python via
Uni.load_rhai_plugin(script, grants=...), with an awaitableAsyncUnicounterpart. - Trusted Python with vectorization → PyO3. Runs Python trusted in-process with vectorized scalar evaluation. Choose it when data scientists author extensions directly in Python and you trust the code. Loadable from Python via
Session.load_python_plugin(...)(and the@session.scalar_fndecorator surface).
Comparison matrix¶
| Loader | Runtime / host | Build target | Wire format | Capability gating | Trust posture | Surfaces (v1) | Load entry point | Python-loadable today |
|---|---|---|---|---|---|---|---|---|
| Rust | in-process native | (host crate) | native trait | compile-time | trusted | all 23 | add_plugin |
no (Rust host only) |
| WASM Component Model | wasmtime + typed WIT worlds | wasm32-wasip2 |
Arrow IPC | declared ∩ granted (reported) | sandboxed | scalar / aggregate / procedure | load_wasm_component |
yes |
| Extism | Extism host-fn ABI | wasm32-unknown-unknown |
Arrow IPC / JSON over linear memory | load-time (host-fn filter) | sandboxed | scalar / aggregate / procedure | load_wasm_extism |
yes |
| Rhai | Rhai scripting engine | none (script) | rhai::Engine values |
load-time (engine factory) | sandboxed | scalar / aggregate / procedure | load_rhai_plugin |
yes (Uni / AsyncUni) |
| PyO3 | in-process Python | (Python module) | PyCapsule / Arrow C Data Interface | manifest + runtime | trusted | scalar / aggregate / procedure (vectorized scalars) | load_python_plugin |
yes (Session) |
Only Rust authors all 23 surfaces today; the other four are limited to scalar, aggregate, and procedure in v1. WASM Component Model and Extism produce byte-identical results for the same logic; Rhai and PyO3 agree to within 4 ULP. All four non-Rust loaders are loadable from Python, but on different entry points: WASM Component Model and Extism load on the instance (Uni / AsyncUni); Rhai also loads on the instance (Uni / AsyncUni); and PyO3 (Python) plugins load on a Session / AsyncSession and are session-scoped. The native Rust loader is the only one without a Python load path — by nature, it is the host embedding.
Per-loader guides¶
- WASM Component Model — typed WIT worlds,
wasm32-wasip2. - Extism — host-fn ABI, load-time capability filtering,
wasm32-unknown-unknown. - Rhai — sandboxed pure-Rust scripting, no build step.
- PyO3 — trusted in-process Python with vectorized scalars.
See also Authoring plugins for the surface-by-surface authoring model, and Trust and capabilities for how grants, sandboxing, and signature policy interact with each loader.