Your First Tengo Extension
A lighter-weight extension entirely in Tengo.
You don't always need a Go binary. If your extension only reacts to events, registers filters, or exposes a simple HTTP route, you can ship it as a pure Tengo package — no gRPC plugin, no migrations, no admin UI required. The reference implementation is resend-provider: the entire transport for Resend email is a settings schema and a Tengo file.
The folder layout
extensions/my-extension/
extension.json # manifest, no plugins[] entry
scripts/
extension.tengo # entry point
handlers/*.tengo # event handlers
filters/*.tengo # filter handlers
routes/*.tengo # route handlers (optional)The manifest
Tengo extensions skip the plugins array. They still declare capabilities — the guard applies whether you call CoreAPI from Go or from Tengo. Common capabilities for a small Tengo extension are settings:read, events:subscribe, http:fetch, log:write.
The entry point
events := import("core/events")
filters := import("core/filters")
routes := import("core/routes")
events.on("node.created", "./handlers/on_node_created")
filters.add("node.title", "./filters/title_suffix", 90)
routes.register("POST", "/hooks/incoming", "./routes/incoming")Handler scripts
Each handler runs in its own short-lived Tengo VM. The script receives a payload map (for events / filters) or a request object (for routes). Set response = {ok: true} for events, response = transformed_value for filters, or response = {status, headers, body} for routes.
What you can't do
The Tengo sandbox blocks arbitrary network connections, arbitrary file reads, and subprocess spawns. Memory and execution time are bounded. If you need any of those things, you're shipping a gRPC plugin — see the previous post.
Resend in twenty lines
The whole resend-provider extension is essentially: declare an email-settings slot in the manifest, subscribe to email.send, and POST the payload to the Resend API via http.fetch. That's it. The Settings UI integrates via the slot exposed by email-manager; nothing to build.
If your idea fits that mould — “react to event X, then talk to service Y” — Tengo is faster to ship and easier to maintain than a gRPC plugin. Reach for Go when you need raw performance, complex state, or a real admin UI.