Every verified stack that runs on Resend.
Resend: transactional email (welcome/notification always; verify/reset when auth is self-hosted).
400 verified stacks
Showing 12 across 12 app types. Every stack page links its neighbours along each axis, so any combination is a click or two from here.
What Resend gives you
Resend covers two jobs: the transactional templates and the module that sends them. `emailTemplates` branches on `framework.slug` — Next.js and React Router get React Email components under `emails/` (`welcome.tsx`, `notification.tsx`, plus `verify-email.tsx` and `reset-password.tsx` when the auth is library-kind), Nuxt gets the same four as `.mjml` files. Both serializations read subject, preview, heading, body lines and CTA label from the shared `EMAIL_COPY` map, so the words are identical and only the markup differs. Every template closes with the `BRAND_ADDRESS` mailing address and an Unsubscribe link, and the React path sets `lang="en"`, a non-empty `<title>` and an explicit `<meta charSet="utf-8">`. `emailSend` emits `lib/email.ts`.
The provider client is built lazily inside `resendClient()` (`client ??= new Resend(process.env.RESEND_API_KEY)`) because `new Resend(undefined)` throws "Missing API key" — at module scope that throw fires at import time, which is exactly when a framework build imports this file to collect page data, so `next build` would fail on any machine holding only runtime secrets. `FROM` reads `EMAIL_FROM` and falls back to Resend's sandbox sender. On Next and React Router each sender awaits `render(WelcomeEmail(props))` from `@react-email/render` — async in the installed 2.1.0 — then calls `resendClient().emails.send({ from, to, subject, html })`.
On Nuxt the templates are inlined as string constants instead, `fill()` substitutes their `{{token}}` placeholders, `mjml2html(src, { validationLevel: "soft" })` compiles them and throws on any returned `errors`, and an ambient `mjml.d.ts` ships alongside because mjml@5 carries no type declarations. Which senders exist is gated on `auth.kind`. Hosted auth gets `sendWelcome` and `sendNotification` only. A library auth additionally gets `sendVerifyEmail` and `sendResetPassword` — the two functions its own config imports back out of this module to fill Better Auth's `emailAndPassword.sendResetPassword` and `emailVerification.sendVerificationEmail` hooks. A hosted provider sends those mails from its own infrastructure.
Built for
`sendVerifyEmail` in `lib/email.ts` renders `emails/verify-email` (React Email) or the `VERIFY_EMAIL_MJML` constant (Nuxt) and sends it under the "Verify your email address" subject. Emitted only for library auth, and it is what Better Auth's `sendVerificationEmail` hook calls.
`sendResetPassword` renders `emails/reset-password` and sends it under the "Reset your password" subject. Also library-auth only — it fills Better Auth's `emailAndPassword.sendResetPassword`, which the server hard-gates on: unset, `POST /request-password-reset` rejects outright.
`sendWelcome` ships on every cell regardless of auth kind, takes `{ name, ctaUrl, unsubscribeUrl }`, and renders the "Welcome aboard" template. It is the one hook an OAuth-only auth can honestly use — Auth.js wires it to `events.createUser`.
`sendNotification` takes `{ name, title, message, ctaUrl, unsubscribeUrl }` and passes `title` through as the Resend subject rather than a fixed string, so a single template and a single sender cover every notification type the app raises.
The lazy `resendClient()` accessor keeps loading `lib/email.ts` free of side effects. A missing `RESEND_API_KEY` surfaces at the send call, where it is actionable, instead of failing the build on CI, a fresh clone, or a preview deploy.
Why Resend, specifically
Template CONTENT (copy/structure/CTA) is shared across formats — only the serialization differs: React Email .tsx on Next/React Router, MJML .mjml on Nuxt.
Every template ships a footer with a physical mailing address + an Unsubscribe link, and lang/title/charset/contrast set explicitly — the concrete set the emailens compatibility/spam/a11y bar checks for.
verify-email/reset-password ship only for library auth (Better Auth, Auth.js) — a hosted auth (Clerk, Supabase) sends its own.
What Resend pulls in
bun add resend @react-email/components @react-email/render mjmlRESEND_API_KEYResend API key (server-side)EMAIL_FROMverified sender address; falls back to Resend's sandbox sender