rate_limit, tenant_scope, owner_stamp, csrf).
Understand the current state before you use it:
- There is no dynamic plugin loading and no
manifest.pluginsarray. Built-ins are registered in the runtime’s Rust code. To ship your own, you build a custom runtime that registers it. - Most needs do not require a plugin. App logic belongs in server functions and policies. Schema-level automation is covered by tenant_scope / owner_stamp / behaviors.
- The SDK exports a
definePlugin({ name, entities, hooks })helper, but the runtime does not consume its output yet. TS-authored plugins are not wired. Treat it as a placeholder, not a supported path.
When to write one
The Plugin trait
This is the real trait, pylon_plugin::Plugin. Every method has a default no-op implementation. Override only what you need:
before_write or after_write method with a WriteOp enum. Insert, update, and delete are separate hooks.
PluginError
Rejections carry a code, message, and HTTP status (it is a struct, not an enum):
Example: a before-insert plugin
This is the pattern the built-ins use: changedata before it is written.
Example: a per-request gate
on_request_with_meta runs before dispatch and receives the peer IP. This is how rate_limit buckets anonymous callers:
Example: adding an HTTP route
routes() returns a list of PluginRoutes. The router matches them after its built-in routes, by method and path prefix. The handler receives (body, path, auth) and returns (status, body):
Registering with the runtime
Plugins are added to aPluginRegistry at boot. This is the same place the built-ins are registered:
crates/runtime), add a reg.register(...) call, and build a custom pylon binary. Dynamic plugin loading and a wired definePlugin remain on the roadmap.
Testing
The trait is plain Rust and needs no wrapper:Reference: the built-ins
Read the real built-ins incrates/plugin/src/builtin/ as templates:
- Before-write data mutation:
tenant_scope.rs,owner_stamp.rs - Per-request gate:
rate_limit.rs,csrf.rs - External-service integration:
ai_proxy.rs