Creating Plugins
This guide covers how to build, package, and install a Windshift plugin.
Prerequisites
- An Extism-compatible language SDK (Rust, Go, JavaScript, C, etc.)
- Basic understanding of WebAssembly
Extism provides PDKs (Plugin Development Kits) for multiple 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, and 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 (containing manifest.json and plugin.wasm) in Windshift's plugin directory. Windshift scans for plugins at startup.
Plugins can be enabled/disabled from the admin panel without restarting the server.
Resource Limits
Plugins run with these default constraints:
| Limit | Value |
|---|---|
| Execution timeout | 5 seconds |
| Memory | 64 MB |
Plugins that exceed these limits are terminated automatically.