Problem
Self-hosted Cap deployments are currently locked into Resend as the only email provider. The relevant code path is in packages/database/emails/config.ts, where sendEmail() is wired directly to the Resend SDK with no abstraction.
For self-hosters, this creates real friction:
- We're forced to add yet another third-party SaaS account just for transactional emails, even when we already operate our own SMTP infrastructure (e.g. Postal, Plunk, Listmonk, AWS SES, or a basic mail relay)
- It contradicts the spirit of self-hosting — moving data ownership away from cloud services
- Without Resend configured, magic links and team invites only appear in container logs (
sendVerificationRequest fallback), which makes onboarding teammates impractical
- The current
accept-invite flow effectively requires email delivery to work end-to-end
Suggested Solution
Add a generic SMTP provider as a first-class alternative. Detection could be as simple as: if SMTP_HOST is set, use SMTP via nodemailer; otherwise fall back to Resend (or logs).
SMTP_HOST=mail.example.com
SMTP_PORT=587
SMTP_USER=...
SMTP_PASSWORD=...
SMTP_FROM=auth@example.com
SMTP_SECURE=false # or true for implicit TLS
The React Email rendering pipeline stays untouched — only the transport layer changes. nodemailer is the de-facto standard in the Node ecosystem for this and integrates cleanly with @react-email/render.
Why this matters
Cap is a fantastic open-source alternative to Loom, and the self-hosting story is a big part of its appeal. SMTP support would close one of the last gaps that currently force users into specific external SaaS providers — which is exactly the lock-in self-hosters try to avoid.
Problem
Self-hosted Cap deployments are currently locked into Resend as the only email provider. The relevant code path is in
packages/database/emails/config.ts, wheresendEmail()is wired directly to the Resend SDK with no abstraction.For self-hosters, this creates real friction:
sendVerificationRequestfallback), which makes onboarding teammates impracticalaccept-inviteflow effectively requires email delivery to work end-to-endSuggested Solution
Add a generic SMTP provider as a first-class alternative. Detection could be as simple as: if
SMTP_HOSTis set, use SMTP vianodemailer; otherwise fall back to Resend (or logs).The React Email rendering pipeline stays untouched — only the transport layer changes.
nodemaileris the de-facto standard in the Node ecosystem for this and integrates cleanly with@react-email/render.Why this matters
Cap is a fantastic open-source alternative to Loom, and the self-hosting story is a big part of its appeal. SMTP support would close one of the last gaps that currently force users into specific external SaaS providers — which is exactly the lock-in self-hosters try to avoid.