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 console-no configuration needed.

For production, you need a Resend API key:

  1. Create an account at resend.com
  2. Add and verify your domain
  3. Generate an API key
  4. Add RESEND_API_KEY as a secret in Cloudflare (see Cloudflare setup)

Configure the sender address in packages/config/index.ts:

email: {
from: "Your App <hello@yourdomain.com>",
}
FunctionModulePurpose
sendEmail(options)@/emailLow-level email sending
sendAuthOtpEmail({ to, otp, env })@/email/templates.serverSend OTP verification code
sendAccessGrantedEmail({ to, env, productName })@/email/templates.serverNotify user of granted access
sendAccessRevokedEmail({ to, env, productName })@/email/templates.serverNotify user of revoked access
sendAccessFailureEmail({ to, env })@/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",
env,
})

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

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

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 /email/sent endpoint (development only)

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