Transport selection
The email package selects Cloudflare's Worker EMAIL binding first, then Cloudflare REST credentials, then the optional Resend fallback, then development console delivery. Deployment setup uses Cloudflare with an onboarded sender domain. Set EMAIL_FROM to the intended display name and address.
Node tooling cannot use the Worker binding. Real Node delivery needs CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_EMAIL_API_TOKEN. A configured Worker binding does not prove Node can send.
Delivery semantics
sendEmailEffect owns the bounded send; its Promise facade serves Better Auth callbacks. There is one send attempt inside the round, with a 10-second timeout. Cloudflare acceptance requires a nonempty message ID. Provider acceptance and inbox receipt are separate checks.
Required verification/recovery mail failures must not report a successful auth action. Informational welcome and security notices have their own handling. Never silently turn required production email into console-only delivery.
Add a template
Add a pure template in templates.ts returning subject, plain text and HTML. Escape user content, pass app branding and URLs explicitly, and call the shared transport. Use a local capture transport in tests; real sends need an explicitly chosen recipient and environment.
Inspect email domain setup for provider onboarding and the previous deployed preview verification for evidence of actual delivery.