Demonstrates how a Go embedder adds a binding that Ramune itself does
not ship. The same pattern works for queues, object stores, caches,
AI providers — any env.FOO you want.
go run .
# in another terminal:
curl -X POST http://localhost:3333/notify \
-H "Content-Type: application/json" \
-d '{"user":"alice@example.com","body":"welcome"}'The Go server prints each EMAIL.send call on stdout:
[EMAIL] to=alice@example.com subject="Hello from Ramune" body="welcome"
main.go— the Go embedder.installEmailBindingregisters__env_email_sendviart.RegisterFunc. That's the actual Go → JS bridge.emailFacadeJSis passed toworkers.WithExtraEnvJS; it attachesenv.EMAIL = { send(opts) { ... } }via theglobalThis.__extraEnvBindings(env)composition hook.workers.Registerwires the worker up; no Ramune changes needed.
worker.ts— the Workers-style handler usesenv.EMAIL.send(...)exactly like it would useenv.KV.get(...).workers-env.d.ts— declares theEnv.EMAILtype so the editor andramune checksee the binding.
The installEmailBinding + emailFacadeJS pair is everything a
reusable ramune-<x> package needs to expose. Keep the IIFE composition
around prev in emailFacadeJS so callers can stack bindings from
multiple packages without collisions:
mailbinding.Install(rt, smtp)
queuebinding.Install(rt, nats)
blobbinding.Install(rt, s3)
extraJS := mailbinding.FacadeJS + queuebinding.FacadeJS + blobbinding.FacadeJS
workers.Register(rt, ..., workers.WithExtraEnvJS(extraJS))See workers/BINDINGS.md for the full
guide.