Overview
Extend RaisFast with plugins — JS, Lua, Rhai, or WASM. Write a working plugin in minutes.
Plugins are the extension mechanism for RaisFast. A plugin is a directory with a manifest.toml and an entry file. That's it.
Your First Plugin
raisfast plugin new my-plugin --runtime jsThis generates:
extensions/plugins/my-plugin/
├── manifest.toml
└── main.jsWrite your first hook handler in main.js:
import { logInfo } from 'sdk';
export function on_content_created(input) {
const data = JSON.parse(input);
logInfo("new content: " + data.id);
}Start the server — the plugin loads automatically. Every time content is created, you'll see the log.
Architecture
manifest.toml entry file (.js / .lua / .rhai / .wasm)
│ │
└─────────┬───────────────┘
▼
PluginManager (Arc-shared)
├─ Topological sort (dependency order)
├─ JS / Lua: per-request (fresh VM each call)
├─ Rhai: per-request (pre-compiled AST, fresh Scope)
├─ WASM: instance pool (round-robin)
└─ Hot-reload (filesystem watcher)
│
▼
Host API (sandboxed, permission-gated)
├─ Database (query / insert / update / delete)
├─ HTTP client (GET / POST)
├─ Virtual filesystem (read / write / list)
├─ KV store (per-plugin namespace)
├─ Config reader
└─ Events, logging, ID generationFour Runtimes
| JavaScript | Lua | Rhai | WASM | |
|---|---|---|---|---|
| Engine | QuickJS | mlua (Lua 5.4) | Rhai | wasmtime |
| Entry | main.js | init.lua | init.rhai | plugin.wasm |
| SDK Import | import { ... } from 'sdk' | local sdk = require("sdk") | None (global scope) | WIT interface |
| Concurrency | Per-request | Per-request | Per-request | Instance pool |
| Language | ES2024 (async/await) | Lua 5.4 | Rust-like DSL | Rust, Go, C, Zig |
| Best for | Quick integrations | Game / embedded devs | Simple automation | Heavy computation |
Three script runtimes can be compiled and loaded simultaneously. WASM is compiled separately via Cargo Feature flags.
JavaScript
import { dbQuery, ok, logInfo } from 'sdk';
export function on_content_created(input) {
const data = JSON.parse(input);
logInfo("created: " + data.id);
}
export function getProducts() {
const rows = dbQuery("SELECT * FROM products");
return ok(rows);
}- Runtime: QuickJS (ES2024, async/await, optional chaining)
- Entry:
main.js - Import SDK:
import { ... } from 'sdk'
Lua
local sdk = require("sdk")
Plugin = {}
Plugin.on_content_created = function(input)
local data = sdk.extractJson(input, "body")
sdk.logInfo("created: " .. tostring(data.id))
end
Plugin.getProducts = function(input)
local rows = sdk.dbQuery("SELECT * FROM products")
return sdk.ok(rows)
end- Runtime: Lua 5.4 (sandboxed: no IO/OS/debug)
- Entry:
init.lua - Import SDK:
local sdk = require("sdk")
Rhai
fn on_content_created(input) {
log("info", "created: " + input.id);
}
fn get_products(input) {
let rows = db_query("SELECT * FROM products", "");
rows
}- Runtime: Rhai (Rust-native scripting, no SDK import needed)
- Entry:
init.rhai - Host functions injected directly into global scope
What Plugins Can Do
| Feature | Description |
|---|---|
| Hooks | React to events — content created, user login, cron tick, etc. |
| Routes | Serve custom REST API endpoints |
| Cron | Schedule background jobs with cron expressions |
| Database | Query and mutate data (permission-gated) |
| HTTP | Make outbound HTTP requests (whitelist-gated) |
| VFS | Per-plugin sandboxed filesystem |
| KV Store | Per-plugin key-value storage |
| Events | Emit and listen to custom events |
Plugin Anatomy
my-plugin/
├── manifest.toml ← metadata, permissions, hooks, routes, cron
└── main.js ← entry file (.js / .lua / .rhai / .wasm)Minimal manifest:
[plugin]
id = "com.example.my-plugin"
name = "My Plugin"
version = "0.1.0"
runtime = "js"
entry = "main.js"Hot Reload
When PLUGIN_HOT_RELOAD=true (default), editing a plugin file reloads it automatically — no server restart needed. 1-second debounce, 2-second poll interval.
Management
# CLI
raisfast plugin check # Validate all plugins
raisfast plugin check ./plugins/my-plugin # Validate specific plugin
# Admin API
GET /api/v1/admin/plugins # List all plugins
GET /api/v1/admin/plugins/{id} # Plugin detail
POST /api/v1/admin/plugins/{id}/reload # Reload a plugin
POST /api/v1/admin/plugins/{id}/disable # Disable
POST /api/v1/admin/plugins/{id}/enable # Enable
DELETE /api/v1/admin/plugins/{id} # UninstallNext
Manifest Reference
Complete manifest.toml schema: plugin info, permissions, hooks, routes, cron.
Hooks
17+ hooks — filter, action, and render override types.
Host API
Complete SDK function reference for all four runtimes.
WASM Plugins
High-performance plugins in Rust, Go, C, or Zig.
Real Example
A complete CRM plugin with hooks, routes, and database.
