Skip to content

Email

Email functionality powered by React Email and Resend. Build beautiful, responsive email templates using React components and send them through Resend’s reliable delivery infrastructure.

Key features

  • React components for email templates
  • TailwindCSS styling support
  • Development mode (logs emails to console, no API key needed)
  • Pre-built templates for authentication and access management

For local development, emails are logged to the dev server console. No configuration needed.

For production and preview environments:

  1. Create a Resend account - sign up at resend.com

  2. Verify your domain - add and verify your domain in the Resend dashboard

  3. Generate an API key - create an API key in the Resend dashboard

  4. Add the secret - add RESEND_API_KEY as a secret in Cloudflare for preview and production environments:

    Terminal window
    bunx wrangler secret put RESEND_API_KEY --env=preview
    Terminal window
    bunx wrangler secret put RESEND_API_KEY --env=production
  5. Configure the sender address - set email.from in packages/config/index.ts:

    email: {
    from: "Your App <hello@yourdomain.com>",
    }
FunctionModulePurpose
sendEmail({ to, subject, react, from? })@/emailLow-level email sending
sendAuthOtpEmail({ to, otp })@/email/templates.serverSend OTP verification code
sendAccessGrantedEmail({ to, productName })@/email/templates.serverNotify user of granted access
sendAccessRevokedEmail({ to, productName })@/email/templates.serverNotify user of revoked access
sendAccessFailureEmail({ to })@/email/templates.serverNotify user of access failure

Use the pre-built template functions for common scenarios:

import { sendAuthOtpEmail } from "@/email/templates.server"
await sendAuthOtpEmail({
to: "user@example.com",
otp: "123456",
})

For custom emails, use the low-level sendEmail function:

import { sendEmail } from "@/email"
import MyCustomEmail from "./templates/my-custom-email"
await sendEmail({
to: "user@example.com",
subject: "Welcome!",
react: <MyCustomEmail name="John" />,
})

The from address defaults to config.email.from. Pass from only when you need a different sender.

Email templates are React components located in apps/email/templates/. They use React Email components for cross-client compatibility.

Preview templates in the browser:

Terminal window
bun dev:email

This starts the React Email development server where you can browse and preview all templates with hot reloading.

Basic template structure:

import { Heading, Text } from "@react-email/components"
import Layout from "./layout"
interface WelcomeEmailProps {
name: string
}
export default function WelcomeEmail({ name }: WelcomeEmailProps) {
return (
<Layout>
<Heading as="h1">Welcome, {name}!</Heading>
<Text>Thanks for signing up.</Text>
</Layout>
)
}

The Layout component provides consistent styling with:

  • TailwindCSS support
  • Custom fonts (Inter)
  • Footer with project name and website link
TemplateFilePurpose
AuthOtpEmailauth-otp.tsxOTP verification code
AccessGrantedEmailaccess.granted.tsxPurchase confirmation
AccessRevokedEmailaccess.revoked.tsxAccess revocation notice
AccessFailureEmailaccess.failure.tsxAccess failure notification

When RESEND_API_KEY is not set (local development), emails are:

  • Logged to the console with full content
  • Stored in memory for testing
  • Accessible via GET /emails/sent endpoint (development only)

In production, sendEmail throws if RESEND_API_KEY is missing.

This allows you to develop and test email flows without sending real emails.