Emails
Emails Overview
Transactional emails with React Email and Resend
The @repo/emails package provides a type-safe email system using React Email for templates and Resend for delivery.
Architecture
Your project imports from @repo/emails (a local workspace package):
your-project/
├── packages/
│ └── emails/ # @repo/emails - local package
│ └── src/
│ ├── index.tsx # sendEmail function
│ ├── lib/
│ │ └── preview-email.ts
│ └── templates/ # Email templates
│ ├── team-invite.tsx
│ └── verify-code.tsx
└── apps/
└── web/ # Imports from @repo/emailsThis architecture means:
- React components as emails - Build emails with JSX and Tailwind
- Type-safe props - Full TypeScript support for template data
- Local preview - Preview emails in browser during development
- Easy customization - Add or modify templates as needed
Features
- React Email - Build emails with React components
- Tailwind CSS - Style emails with familiar utility classes
- Type-safe templates - TypeScript props for each email type
- Dev preview - Opens emails in browser during development
- Resend integration - Production-ready email delivery
Usage
sendEmail
The main function for sending emails:
import { sendEmail } from "@repo/emails"
const { data, error } = await sendEmail({
template: "TeamInvite", // Template name (required)
to: "[email protected]", // Recipient (required)
from: "[email protected]", // Sender (required)
subject: "You're invited", // Subject line (required)
props: { // Template props (type-safe)
teamName: "Acme Inc",
inviteLink: "https://..."
}
})| Parameter | Type | Description |
|---|---|---|
template | string | Template name matching file in templates/ |
to | string | Recipient email address |
from | string | Sender email address |
subject | string | Email subject line |
props | object | Type-safe props for the template |
replyTo | string? | Optional reply-to address |
Return value
interface SendEmailResult {
data: { id: string } | null // Resend message ID
error: Error | null // Error if failed
}Error handling
const { data, error } = await sendEmail({ ... })
if (error) {
console.error("Failed to send email:", error.message)
return
}
console.log("Email sent:", data.id)Quick Start
Send an email
import { sendEmail } from "@repo/emails"
export async function POST(request: Request) {
const { email, teamName, inviteLink } = await request.json()
const { data, error } = await sendEmail({
template: "TeamInvite",
from: "[email protected]",
to: email,
subject: `You've been invited to ${teamName}`,
props: {
email,
invitedByName: "Alex",
teamName,
inviteLink
}
})
if (error) {
return Response.json({ error: error.message }, { status: 500 })
}
return Response.json({ success: true })
}Environment Setup
Add your Resend API key to .env.local:
RESEND_API_KEY="re_xxxxxxxxxxxxx"Get your API key from resend.com/api-keys.
Development Mode
In development, emails are not sent to Resend. Instead, they open in your browser for preview:
📧 Email preview opened in browser: /tmp/email-previews/email-1234567890.htmlThis allows you to iterate on templates without sending real emails or using API credits.
To force sending emails in development:
RESEND_ENABLED=truePreview Templates
Run the React Email dev server to preview templates with hot reload:
pnpm devOpens at http://localhost:5001 with a visual editor for your templates.
Included Templates
| Template | Purpose |
|---|---|
TeamInvite | Team invitation email with accept button |
VerifyCode | OTP/verification code email |
Next Steps
- Email templates - Create and customize templates
- Sending emails - API usage and patterns