Publish a plugin
Three commands from scaffolding to published package.
1. Create
Scaffold a new plugin. Pick a sandbox: quickjs for JS, wasm for compiled code, nsjail for system access.
$ bext plugin init my-plugin --sandbox quickjs2. Test
Run your plugin locally. Hot-reloads on save, shows sandbox logs.
$ bext dev --plugin ./my-plugin3. Publish
Authenticates via GitHub, runs security scans, and makes the plugin available.
$ bext plugin publishManifest
Every plugin needs a bext.plugin.toml at the root.
bext.plugin.toml
[plugin]
name = "bext-plugin-my-plugin"
version = "1.0.0"
description = "What your plugin does"
license = "MIT"
author = "your-github-username"
[plugin.sandbox]
type = "quickjs" # quickjs | wasm | nsjail
memory_limit = "64mb"
timeout = "5s"
[plugin.hooks]
on_request = "src/on_request.ts"
on_response = "src/on_response.ts"
[plugin.config]
api_key = { type = "string", required = true, env = "MY_PLUGIN_API_KEY" }
max_retries = { type = "integer", default = 3 }
Hooks
Plugins hook into the request lifecycle. Intercept requests, modify responses, or run background work.
src/on_request.ts
import type { BextRequest, BextResponse } from "bext:plugin";
export function onRequest(req: BextRequest): BextRequest | BextResponse {
const apiKey = req.headers.get("x-api-key");
if (!apiKey) {
return new BextResponse("Unauthorized", { status: 401 });
}
return req;
}
export function onResponse(req: BextRequest, res: BextResponse): BextResponse {
res.headers.set("X-Plugin-Version", "1.0.0");
return res;
}
Guidelines
- Names must start with
bext-plugin- - Include a README with usage examples
- Pin sandbox memory and timeout limits
- Add at least one integration test
- Use semver for releases
- Don't bundle secrets in the package