Creating Plugins
This guide covers how to build, package, and install a Windshift plugin.
Prerequisites
- An Extism-compatible language SDK, such as Rust, Go, JavaScript, or C.
- A basic understanding of WebAssembly.
Extism provides Plugin Development Kits (PDKs) for several languages. See extism.org for the full list.
Project Structure
my-plugin/
├── manifest.json # Plugin metadata and extensions
├── src/ # Plugin source code
├── plugin.wasm # Compiled WASM binary
└── index.html # Optional UI (for iframe extensions)Manifest
Every plugin requires a manifest.json:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "What this plugin does",
"entryPoint": "plugin.wasm",
"extensions": []
}Fields
| Field | Required | Description |
|---|---|---|
name |
Yes | Unique plugin identifier |
version |
Yes | Semantic version |
description |
Yes | Human-readable description |
entryPoint |
Yes | Path to the WASM binary |
extensions |
No | List of UI extension registrations |
Extensions
To add a UI tab in the admin panel:
{
"extensions": [
{
"point": "admin.tab",
"id": "my-plugin-tab",
"label": "My Plugin",
"displayMode": "iframe",
"component": "index.html",
"group": "Tools"
}
]
}| Field | Description |
|---|---|
point |
Extension point (e.g., admin.tab) |
id |
Unique extension identifier |
label |
Display name in the UI |
displayMode |
How to render: iframe for HTML content |
component |
Path to the HTML file |
group |
Group name in the admin sidebar |
Writing Plugin Code
Plugins export functions that Windshift calls. They import host functions to interact with the platform.
Example (Go with Extism PDK)
package main
import (
"github.com/extism/go-pdk"
)
//export run
func run() int32 {
// Call a host function
pdk.Log(pdk.LogInfo, "Plugin executing")
// Read input
input := pdk.Input()
// Do work...
// Write output
pdk.OutputString("done")
return 0
}
func main() {}Example (JavaScript with Extism PDK)
function run() {
Host.log("info", "Plugin executing");
const input = Host.inputString();
// Do work...
Host.outputString("done");
return 0;
}
module.exports = { run };Building
Compile your plugin to a WASM binary using the Extism toolchain for your language:
# Go
tinygo build -o plugin.wasm -target wasi .
# Rust
cargo build --target wasm32-wasi --release
cp target/wasm32-wasi/release/my_plugin.wasm plugin.wasm
# JavaScript (using Extism JS PDK)
extism-js src/index.js -o plugin.wasmInstalling
Place the plugin directory, including manifest.json and plugin.wasm, in Windshift's plugin directory. Windshift scans for plugins when it starts.
You can enable or disable plugins in the admin panel without restarting the server.
Resource Limits
Plugins run with these default constraints:
| Limit | Value |
|---|---|
| Execution timeout | 5 seconds |
| Memory | 64 MB |
Windshift terminates plugins that exceed these limits.