---
name: react-email
description: Use when creating email templates with React - welcome emails, password resets, notifications, order confirmations, or transactional emails that need to render across email clients.
---
# React Email
## Overview
Build and send HTML emails using React components. A modern, component-based approach to email development that works across all major email clients by compiling to compatible HTML.
## When to Use
- Creating transactional emails (welcome, password reset, order confirmation)
- Building notification or marketing email templates
- Need consistent rendering across Gmail, Outlook, Apple Mail, Yahoo
- Want component reusability and TypeScript support in emails
- Integrating with email providers like Resend, SendGrid, Postmark
**When NOT to use:**
- Simple plain-text emails
- Emails that don't need cross-client compatibility
- Projects without React/Node.js
## Installation
Scaffold a new React Email project:
```sh
npx create-email@latest
```
Equivalent commands: `yarn create email`, `pnpm create email`, `bun create email`
Then install dependencies and start the dev server:
```sh
cd react-email-starter
npm install
npm run dev
```
The server runs at localhost:3000 with a preview interface for templates in the `emails` folder.
### Adding to an Existing Project
Add dependencies to run the email server:
```bash
npm install react-email @react-email/preview-server -D -E
npm install @react-email/components react react-dom -E
```
Add a script to your package.json:
```json
{
"scripts": {
"email:dev": "email dev"
}
}
```
If the emails are in a different folder, you can specify the directory:
```json
{
"scripts": {
"email:dev": "email dev --dir src/emails"
}
}
```
Ensure tsconfig.json includes proper JSX support.
## Basic Email Template
Create an email component with proper structure using the Tailwind component for styling:
```tsx
import {
Html,
Head,
Preview,
Body,
Container,
Heading,
Text,
Button,
Tailwind,
pixelBasedPreset,
} from "@react-email/components";
interface WelcomeEmailProps {
name: string;
verificationUrl: string;
}
export default function WelcomeEmail({ name, verificationUrl }: WelcomeEmailProps) {
return (
Welcome - Verify your emailWelcome!Hi {name}, thanks for signing up!
);
}
WelcomeEmail.PreviewProps = {
name: "John Doe",
verificationUrl: "https://example.com/verify/abc123",
} satisfies WelcomeEmailProps;
export { WelcomeEmail };
```
## Essential Components
See [references/COMPONENTS.md](references/COMPONENTS.md) for complete component documentation.
**Core Structure:**
- `Html` - Root wrapper with `lang` attribute
- `Head` - Meta elements, styles, fonts
- `Body` - Main content wrapper
- `Container` - Centers content (max-width layout)
- `Section` - Layout sections
- `Row` & `Column` - Multi-column layouts (table-based, won't stack on mobile)
- `Tailwind` - Enables Tailwind CSS utility classes
**Content:**
- `Preview` - Inbox preview text, place immediately after `Body` opening tag
- `Heading` - h1-h6 headings
- `Text` - Paragraphs
- `Button` - Styled link buttons
- `Link` - Hyperlinks
- `Img` - Images (use absolute URLs; copy local images to `/emails/static/` and use dev server BASE_URL in dev, ask user for production BASE_URL)
- `Hr` - Horizontal dividers
**Specialized:**
- `CodeBlock` - Syntax-highlighted code
- `CodeInline` - Inline code
- `Markdown` - Render markdown
- `Font` - Custom web fonts
## Behavioral Guidelines
- When re-iterating over code, only update what the user asked for
- If the user asks for media queries, inform them email clients don't support them and suggest alternatives
- Never use template variables (like `{{name}}`) directly in TypeScript code - reference props directly
For example, if the user explicitly asks for a variable following the pattern `{{variableName}}`:
```typescript
const EmailTemplate = (props) => {
return (
Hello, {props.variableName}!
);
}
EmailTemplate.PreviewProps = {
variableName: "{{variableName}}",
};
export default EmailTemplate;
```
Never write the `{{variableName}}` pattern directly in the component structure - explain this makes the template invalid.
## Styling
See [references/STYLING.md](references/STYLING.md) for complete styling documentation, including shared Tailwind config patterns for multiple templates.
**Key rules:**
- Use `pixelBasedPreset` - email clients don't support `rem` units
- Never use flexbox/grid - use `Row`/`Column` components
- Never use SVG/WEBP images - use PNG/JPEG only
- Never use media queries (`sm:`, `md:`) or theme selectors (`dark:`)
- Always specify border type (`border-solid`, `border-dashed`)
- Always use `box-border` on buttons
## Rendering
### Convert to HTML
```tsx
import { render } from "@react-email/components";
import { WelcomeEmail } from "./emails/welcome";
const html = await render(
);
```
### Convert to Plain Text
```tsx
import { render } from "@react-email/components";
import { WelcomeEmail } from "./emails/welcome";
const text = await render(
,
{ plainText: true }
);
```
## Sending
React Email supports any email service provider. See [references/SENDING.md](references/SENDING.md) for details.
Quick example using Resend:
```tsx
import { Resend } from "resend";
import { WelcomeEmail } from "./emails/welcome";
const resend = new Resend(process.env.RESEND_API_KEY);
const { data, error } = await resend.emails.send({
from: "Acme ",
to: ["user@example.com"],
subject: "Welcome to Acme",
react: ,
});
if (error) {
console.error("Failed to send:", error);
}
```
Resend can receive a React component directly. If not included in the call, Resend will automatically include a plain-text version of the email.
## Internationalization
See [references/I18N.md](references/I18N.md) for complete i18n documentation with examples for next-intl, react-i18next, and react-intl.
## Common Mistakes
| Mistake | Fix |
| ---------------------------------------- | ---------------------------------------------------------- |
| Using flexbox/grid | Use `Row` and `Column` components or tables |
| Using `rem` units | Use `pixelBasedPreset` with Tailwind |
| Using SVG images | Use PNG or JPG instead |
| Using media queries (sm:, md:) | Design mobile-first with stacked layouts |
| Template vars in JSX (`{{name}}`) | Use props: `{props.name}` |
| Missing border type | Always specify: `border-solid`, `border-dashed`, etc. |
| Fixed image dimensions on content images | Use responsive: `w-full h-auto` (fixed OK for small icons) |
| Emails over 102KB | Gmail clips larger emails - reduce size |
## Best Practices
1. **Test across clients** - Gmail, Outlook, Apple Mail, Yahoo. Use Litmus or Email on Acid for precision.
2. **Keep it responsive** - Max-width ~600px, test on mobile.
3. **Use absolute image URLs** - Host on reliable CDN, always include `alt` text. If local development, copy to `emails/static/`.
4. **Provide plain text version** - Required for accessibility.
5. **Add TypeScript types** - Define interfaces for all email props.
6. **Include PreviewProps** - For development testing.
7. **Handle errors** - Always check for errors when sending.
8. **Use verified domains** - For production `from` addresses.
## Additional Resources
- [React Email Documentation](https://react.email/docs/llms.txt)
- [React Email GitHub](https://github.com/resend/react-email)
- [Resend Documentation](https://resend.com/docs/llms.txt)
- [Email Client CSS Support](https://www.caniemail.com)
- Component Reference: [references/COMPONENTS.md](references/COMPONENTS.md)
- Internationalization Guide: [references/I18N.md](references/I18N.md)
- Common Patterns: [references/PATTERNS.md](references/PATTERNS.md)
- Sending Guide: [references/SENDING.md](references/SENDING.md)