Email

Provider-agnostic transactional email with a local preview workflow.

Providers

Email is configured by EMAIL_PROVIDER, with credentials validated per provider at boot:

ProviderUseRequired env
previewDevelopment default: captures emails, optionally opens a browser preview tabnone
noneExplicit opt-out: nothing sends (sign-up verification will not work)none
resendProductionRESEND_API_KEY
plunkProductionPLUNK_API_KEY
sesProduction (AWS)AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY

Production refuses preview; none is allowed as a deliberate choice for demos.

What sends email

The auth flows: sign-up verification, password reset, and magic links. Plus admin notifications: contact form submissions and newsletter sign-ups route to EMAIL_ADMIN_TO when configured.

Sender identity comes from EMAIL_FROM (display name and address), with EMAIL_REPLY_TO for responses.

Local preview

With the default preview provider and EMAIL_PREVIEW_OPEN_TAB=true, every email your dev server sends opens in a browser tab rendered exactly as it would deliver. No SMTP, no sandbox accounts, no checking a real inbox.

Templates

Templates are React components in src/domain/email/templates/, rendered through React Email: auth templates (verification, reset, magic link) and marketing templates (contact notification, newsletter notification). Edit them like any component; the preview workflow gives immediate feedback.

Rate limiting

A lightweight in-memory rate limiter (src/domain/email/rate-limit.ts) guards send paths from abuse. It is keyed and windowed, and the same utility is reused by other abuse-sensitive endpoints like AI chat.