manifest.plugins: [...] list. There is no such array today.
- TS packages (
@pylonsync/*) — installable npm packages that return a manifest fragment (entities, actions, queries, policies) plus handler factories. You compose the fragment into yourbuildManifest()call. Use these to add features the framework binary doesn’t already cover. - Built-in runtime plugins — a small set compiled into the
pylonbinary and wired automatically from your schema or environment. You don’t name them anywhere; they activate when the relevant signal is present (atenantIdfield, a.owner()annotation, an env var).
- API keys —
/api/auth/api-keysroutes for mint / list / revoke. See Auth → API keys. - TOTP / 2FA —
/api/auth/totp/*routes for enroll / verify / disable + backup codes. See Auth → TOTP. - Transactional email —
PYLON_EMAIL_PROVIDERenv (sendgrid / resend / stack0 / webhook) +ctx.email.send(). See Integrations → email. - Audit log —
/api/auth/audit+/api/auth/audit/tenantroutes. - Organizations —
Org/OrgMember/OrgInviteentities +/api/auth/orgs/*routes. See Auth → Organizations.
TS packages
Install withbun add, then spread the manifest fragment into buildManifest():
| Package | Purpose |
|---|---|
| @pylonsync/stripe | Declarative billing — plans, checkout, portal, cancel/restore, signature-verified webhook, subscription entity. |
| @pylonsync/feature-flags | Local-eval flags — boolean + multivariate, percentage rollouts, targeting predicates, per-variant JSON payloads. |
| @pylonsync/webhooks | Outbound webhook delivery — Svix-compatible HMAC signatures, retry schedule, secret rotation. |
stripe({...}), webhooks({...})) that returns { manifest, handlers, ... }. Pylon loads function handlers one-per-file, so you also add one-line wrapper files under functions/ — see each package’s page for the exact list.
Built-in runtime plugins
These live incrates/plugin/src/builtin/ and are registered by the runtime at boot. They are auto-wired, not enabled through a manifest list.
| Built-in | How it turns on | Reference |
|---|---|---|
tenant_scope | Automatic on any entity with a tenantId field | Data hygiene |
owner_stamp | Automatic on any field declared field.X().owner() | Data hygiene |
rate_limit | Always on; tuned via PYLON_RATE_LIMIT_MAX* env | Security |
csrf | Always on; allowlist from manifest.auth.trustedOrigins / env | Security |
LLM proxy (ai_proxy) | Env-configured; powers /api/llm/complete, /api/ai/stream, ctx.llm | Search & AI |
| In-process cache | Internal; backs SSR / ISR response caching | — |
How built-ins hook in
Built-ins observe the request and data path at fixed points. The exact Rust hooks (see Writing your own):on_request), mutate or reject a write (before_*), react after a write lands (after_*), add HTTP routes (routes()), or contribute manifest entities (entities()).
There is no plugins: [] array
Older drafts of these docs described enabling plugins through a pylon.manifest.json plugins list with per-plugin config. That mechanism does not exist. Built-ins are automatic; you influence them through your schema (add a tenantId field, annotate a field .owner()) and environment variables. App-specific cross-cutting logic goes in server functions and policies, not a plugin config block.
pylon plugins list prints a roadmap catalog of plugin names (validation, slugify, versioning, cascade, MCP, and more). These are planned, not installable today — treat the list as a preview, not an API.
Plugins vs functions
| Plugins / built-ins | Functions |
|---|---|
| Implicit — fire on every relevant op | Explicit — called by name |
| Auto-wired from schema/env, or composed from a TS package | Defined in TS files under functions/ |
| Can mutate data in-flight (built-ins) | Run inside a transaction; return a result |
| Cross-cutting concerns (tenant scope, owner stamp, rate limit) | Business logic |
| Compiled into the binary, or shipped as a package | Hot-reloaded by the dev server |
Writing your own
There is no dynamic plugin loading yet. To add a Rust built-in you build a custom runtime that registers it; for TypeScript-side logic, use functions and policies. The SDK ships adefinePlugin({ name, entities, hooks }) helper, but the runtime does not consume its output yet. See Writing your own plugin for the real Plugin trait and the honest state of extensibility.