Skip to main content

Overview

This guide will walk you through creating a complete email template using React Email, rendering it to HTML, and sending it with an email provider.
1

Install React Email

First, install the components package:
npm install @react-email/components
2

Create Your First Email

Create a new file for your email template:
emails/welcome.tsx
import {
  Body,
  Container,
  Head,
  Heading,
  Html,
  Preview,
  Text,
} from '@react-email/components';

interface WelcomeEmailProps {
  name: string;
}

export const WelcomeEmail: React.FC<Readonly<WelcomeEmailProps>> = ({
  name,
}) => (
  <Html>
    <Head />
    <Body style={main}>
      <Preview>
        Welcome to our platform! We're excited to have you.
      </Preview>
      <Container style={container}>
        <Heading style={h1}>Welcome aboard!</Heading>
        <Text style={text}>
          Hi {name}, thank you for joining our platform. We're excited to
          have you on board and can't wait to see what you'll create.
        </Text>
      </Container>
    </Body>
  </Html>
);

export default WelcomeEmail;

const main = {
  backgroundColor: '#ffffff',
  fontFamily:
    '-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif',
};

const container = {
  margin: '0 auto',
  padding: '20px 0 48px',
  maxWidth: '560px',
};

const h1 = {
  color: '#333',
  fontSize: '24px',
  fontWeight: '600',
  lineHeight: '40px',
  margin: '0 0 20px',
};

const text = {
  color: '#666',
  fontSize: '14px',
  lineHeight: '24px',
  margin: '0 0 40px',
};
The Preview component sets the preview text that appears in email clients before opening the email.
3

Preview Your Email

Start the development server to see your email in the browser:
npx react-email dev
Open http://localhost:3000 to see your email with live reload.
The dev server watches for file changes and automatically reloads, making it easy to iterate on your design.
4

Render to HTML

To send your email, you need to convert it to HTML using the render function:
import { render } from '@react-email/components';
import { WelcomeEmail } from './emails/welcome';

const emailHtml = await render(<WelcomeEmail name="Alice" />);
The render function returns a Promise that resolves to an HTML string optimized for email clients.
5

Send Your Email

Now you can send the HTML with any email provider. Here’s an example with Nodemailer:
import { render } from '@react-email/components';
import nodemailer from 'nodemailer';
import { WelcomeEmail } from './emails/welcome';

const transporter = nodemailer.createTransport({
  host: 'smtp.forwardemail.net',
  port: 465,
  secure: true,
  auth: {
    user: 'my_user',
    pass: 'my_password',
  },
});

const emailHtml = await render(<WelcomeEmail name="Alice" />);

const options = {
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Welcome to our platform!',
  html: emailHtml,
};

await transporter.sendMail(options);

Add a Button

Let’s enhance the email by adding a call-to-action button:
emails/welcome.tsx
import {
  Body,
  Button,
  Container,
  Head,
  Heading,
  Html,
  Preview,
  Text,
} from '@react-email/components';

interface WelcomeEmailProps {
  name: string;
  loginUrl: string;
}

export const WelcomeEmail: React.FC<Readonly<WelcomeEmailProps>> = ({
  name,
  loginUrl,
}) => (
  <Html>
    <Head />
    <Body style={main}>
      <Preview>
        Welcome to our platform! We're excited to have you.
      </Preview>
      <Container style={container}>
        <Heading style={h1}>Welcome aboard!</Heading>
        <Text style={text}>
          Hi {name}, thank you for joining our platform. We're excited to
          have you on board and can't wait to see what you'll create.
        </Text>
        <Button style={button} href={loginUrl}>
          Get Started
        </Button>
      </Container>
    </Body>
  </Html>
);

export default WelcomeEmail;

const main = {
  backgroundColor: '#ffffff',
  fontFamily:
    '-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif',
};

const container = {
  margin: '0 auto',
  padding: '20px 0 48px',
  maxWidth: '560px',
};

const h1 = {
  color: '#333',
  fontSize: '24px',
  fontWeight: '600',
  lineHeight: '40px',
  margin: '0 0 20px',
};

const text = {
  color: '#666',
  fontSize: '14px',
  lineHeight: '24px',
  margin: '0 0 10px',
};

const button = {
  backgroundColor: '#5469d4',
  borderRadius: '4px',
  color: '#fff',
  fontSize: '16px',
  fontWeight: '600',
  textDecoration: 'none',
  textAlign: 'center' as const,
  display: 'block',
  padding: '12px 20px',
};
The button will render as a styled link that works reliably across all email clients.

Styling Best Practices

React Email components accept inline styles for maximum email client compatibility:

Use Inline Styles

Email clients have limited CSS support. Always use inline styles with the style prop.

Define Style Objects

Create reusable style objects for consistency and maintainability.

Avoid CSS Classes

Most email clients don’t support CSS classes. Stick to inline styles.

Use Tailwind (Optional)

The Tailwind component can convert utility classes to inline styles.

Common Email Patterns

import { Html, Button, Text, Container } from '@react-email/components';

export default function OrderConfirmation({ orderNumber, trackingUrl }) {
  return (
    <Html>
      <Container>
        <Text>Your order #{orderNumber} has shipped!</Text>
        <Button href={trackingUrl}>Track Package</Button>
      </Container>
    </Html>
  );
}
import { Html, Section, Heading, Text, Link } from '@react-email/components';

export default function Newsletter({ articles }) {
  return (
    <Html>
      {articles.map((article) => (
        <Section key={article.id}>
          <Heading>{article.title}</Heading>
          <Text>{article.excerpt}</Text>
          <Link href={article.url}>Read more</Link>
        </Section>
      ))}
    </Html>
  );
}
import { Html, Body, Container, Heading, Text, Button } from '@react-email/components';

export default function Welcome({ name, verifyUrl }) {
  return (
    <Html>
      <Body>
        <Container>
          <Heading>Welcome {name}!</Heading>
          <Text>Thanks for signing up. Please verify your email.</Text>
          <Button href={verifyUrl}>Verify Email</Button>
        </Container>
      </Body>
    </Html>
  );
}

Working with Images

Add images using the Img component:
import { Img, Html, Container } from '@react-email/components';

export default function Email() {
  return (
    <Html>
      <Container>
        <Img
          src="https://example.com/logo.png"
          width="150"
          height="50"
          alt="Company Logo"
        />
      </Container>
    </Html>
  );
}
Always use absolute URLs for images. Email clients don’t support relative paths.

Email Provider Integration

React Email works with all major email providers:

Resend

Modern email API with great React Email support

Nodemailer

Popular Node.js email sending library

SendGrid

Scalable email delivery platform

AWS SES

Amazon’s email sending service

Export to Static HTML

You can export all your emails to static HTML files:
npx react-email export
This creates an out directory with HTML files for each email template.
Static exports are useful for version control, testing, or using with email systems that don’t support dynamic rendering.

Next Steps

Explore Components

Learn about all available React Email components

Render API

Advanced rendering options and configurations

Integrations

Set up React Email with your email provider

Examples

Browse real-world email template examples

Build docs developers (and LLMs) love