Email

Which emails the app sends, the three mailers (SMTP, Resend, log only), and how email works locally.

Last updated

Two systems send email:

  • Supabase Auth sends sign-in emails: confirmation, password reset, email change, magic link. Configure them in Supabase. See Email sign-in.
  • The app sends everything else through @repo/mailers (packages/mailers).

What the app sends

EmailSent fromTemplate
Team invitationaccount-invitations-dispatcher.service.tsinvite.email.tsx
One-time code for a sensitive action (delete an account or team, transfer ownership)packages/otpotp.email.tsx
Confirmation after a personal account is deleteddelete-personal-account.service.tsaccount-delete.email.tsx
Contact form message, to you(marketing)/contactInline HTML in the server action
Showcase submission, to you(marketing)/showcaseInline HTML in the server action

The templates are React Email components in packages/email-templates/src/emails/, with their text in packages/email-templates/src/locales/en/. The developer tool (http://localhost:3010, started by pnpm dev) has an emails page for previewing them.

Pick a mailer

MAILER_PROVIDER chooses how the app's emails go out:

ValueSends withNeeds
nodemailer (default)Any SMTP serverEMAIL_HOST, EMAIL_PORT, EMAIL_USER, EMAIL_PASSWORD, EMAIL_TLS (TLS stays on unless set to false). Node.js runtime only
resendResend's HTTP APIRESEND_API_KEY
logNothing. Logs the recipient's domain and the subjectNothing

Every email the app sends uses EMAIL_SENDER as the from address, for example "Your product <hello@yourdomain.com>". The contact form and showcase form need CONTACT_EMAIL, the address that receives them.

log is for places where email must not reach real inboxes, such as the live demo. It logs only the domain, not the full address, so logs do not collect what visitors typed.

Locally

apps/web/.env.development sets MAILER_PROVIDER=nodemailer and points it at the local Supabase stack's mail server on port 54325. Supabase Auth's local emails go to the same inbox. Open Mailpit at http://localhost:54324 to read everything that was sent.

How do you raise Supabase's auth email rate limit?

Set up custom SMTP for your Supabase project, then raise the limit on its Rate Limits page. Supabase lets you change that limit only once auth emails go through custom SMTP (or a Send Email hook), not its built-in sender.

As of October 2026, the built-in sender is for testing only: it delivers just to members of your Supabase organisation's team, at 2 emails an hour. Confirmation, password reset and magic link emails to anyone else fail until you add your own SMTP server.

  1. Pick a sending service that offers SMTP. Resend does, and Supabase's guide lists others.
  2. In the Supabase dashboard, open the project's Authentication settings, turn on custom SMTP, and enter the host, port, user, password and sender address.
  3. Save. Supabase now sends to every address, starting at a low limit of 30 emails an hour.
  4. Open Authentication > Rate Limits and raise the limit on emails sent to what your sign-ups need. The Management API sets the same value as rate_limit_email_sent.

Locally none of this applies: apps/web/supabase/config.toml sets email_sent = 1000 under [auth.rate_limit], and Mailpit catches everything. Supabase's custom SMTP guide and rate limits page have the current numbers.

Add another provider

Add the name to packages/mailers/core/src/provider-enum.ts and register a factory for it in packages/mailers/core/src/registry.ts that returns an object with sendEmail(). The log mailer in that file is a short example.

Live demo

Resets hourly

Get the kit