ShipVeryFastShipVeryFast
Documentation

Swap Mailgun for Resend

All email goes through one sender, libs/mailer.ts. Swap its body for Resend and every transactional email (verification, reset, welcome, magic links) follows, with no changes to templates or call sites.

The seam

libs/emailService.ts decides what to send and libs/emailTemplates.ts renders it. Both call libs/mailer.ts to actually deliver. Only the mailer knows the provider.

Install Resend and add a key

npm install resend

Add RESEND_API_KEY to libs/config.ts and set it in your env. You can drop the Mailgun vars once the swap is done.

Rewrite the mailer

Keep the same function signature so callers do not change.

libs/mailer.ts
import { Resend } from "resend";

const resend = new Resend(env.RESEND_API_KEY);

export async function sendEmail({ to, subject, html }: SendEmailArgs) {
  await resend.emails.send({ from: env.EMAIL_FROM, to, subject, html });
}

Verify your domain

Add your sending domain in the Resend dashboard and set its DNS records. Until the domain verifies, Resend only delivers to your own address, which is fine for local testing.

Magic links still work

Because NextAuth's email provider sends through the same mailer, magic link sign-in keeps working after the swap with no extra wiring.