Mailing
Transactional email uses Resend and React Email templates that live next to the feature that sends them. The free template wires the Resend client; packs add the templates and call sites.
Client
// apps/backend/src/libs/email/resend.ts
import { Resend } from "resend";
export const resend = new Resend(process.env.RESEND_API_KEY);The From address is built from RESEND_FROM_DOMAIN (see app constants). Without RESEND_API_KEY, optional send paths
(billing receipts, some notification channels) skip email instead of failing the request. Auth and invitation flows that
require email will not work until the key is set.
Environment variables
| Variable | Purpose |
|---|---|
RESEND_API_KEY | Resend API key |
RESEND_FROM_DOMAIN | Domain used for the From address |
Template locations
Templates are React Email components colocated under feature modules, for example:
| Typical path | |
|---|---|
| Password reset / changed | features/auth/modules/*/emails/*.tsx |
| Organization invitation | features/organizations/modules/send-organization-invitation/emails/ |
| Billing receipt | features/billing/modules/send-receipt/emails/receipt.tsx |
| Admin notification | features/notifications/.../emails/admin-notification.tsx |
Send sites call resend.emails.send({ from, to, subject, react }) (or HTML) directly from the module. There is no
separate email microservice.
Trigger points
| Flow | When it sends |
|---|---|
| Auth | Password reset, email verification (starter-dependent) |
| Organizations | Invitation email on send / resend |
| Billing | Receipt after successful payment when Resend is configured |
| Notifications | Optional email channel when admins target specific users |
Frontend links inside emails should use the frontendUrl() helper so paths and query params stay typed against
FRONTEND_URL.
Adding a template
- Create a React Email component next to the module that will send it
- Call
resend.emails.sendfrom that module with the component asreact - Keep provider-specific HTTP details in
libs/email - Document any new env needs in
.env.example
Related
Every purchase and sponsorship funds my 8+ years of work on open source given freely to the community. It keeps the lights on, funds new packs, and keeps the ecosystem alive. Even a small tier means a lot. Thank you!
