react-email
Build cross-client compatible HTML emails using React components.
Fit
Bundle (gzip)
523.8 kB
1.8 MB raw
Install size includes transitive dependencies. Bundle size is gzipped browser payload.
Freshness
The Problem
HTML emails are notoriously difficult to build. Unlike the modern web, email clients have extremely inconsistent CSS support:
- Gmail strips
<style>tags in some contexts and requires inline styles - Outlook uses Microsoft Word's rendering engine (yes, really), which breaks flexbox, grid, and most modern CSS
- Apple Mail is more forgiving, which makes cross-testing even more confusing
The result: you spend hours writing table-based layouts with inline styles, testing in 5+ clients, and watching things break in ways that make no sense.
This was discovered after hours of fighting email templates — then a LinkedIn post mentioned react-email and everything changed.
What It Does
React Email lets you write email templates as React components using a set of purpose-built primitives (<Html>, <Body>, <Section>, <Button>, etc.) that compile down to email-safe HTML. It handles cross-client compatibility so you don't have to think about it.
It also ships with a local preview server that shows your email rendered in a browser as you develop — no more sending test emails to yourself.
Installation
npm install react-email @react-email/componentsUsage Example
Basic welcome email
import {
Html,
Head,
Body,
Container,
Section,
Text,
Button,
Hr,
} from "@react-email/components";
interface WelcomeEmailProps {
username: string;
}
export default function WelcomeEmail({ username }: WelcomeEmailProps) {
return (
<Html>
<Head />
<Body style={{ backgroundColor: "#f6f9fc", fontFamily: "sans-serif" }}>
<Container style={{ maxWidth: "600px", margin: "0 auto", padding: "40px 0" }}>
<Section style={{ backgroundColor: "#ffffff", padding: "40px", borderRadius: "8px" }}>
<Text style={{ fontSize: "24px", fontWeight: "bold", color: "#1a1a1a" }}>
Welcome, {username}!
</Text>
<Text style={{ fontSize: "16px", color: "#555", lineHeight: "1.6" }}>
We're glad you're here. Click below to get started.
</Text>
<Hr />
<Button
href="https://yourapp.com/dashboard"
style={{
backgroundColor: "#5c6bc0",
color: "#ffffff",
padding: "12px 24px",
borderRadius: "4px",
textDecoration: "none",
display: "inline-block",
}}
>
Go to Dashboard
</Button>
</Section>
</Container>
</Body>
</Html>
);
}Rendering to HTML (for sending via any email provider)
import { render } from "@react-email/render";
import WelcomeEmail from "./emails/WelcomeEmail";
const html = render(<WelcomeEmail username="Sarah" />);
// Pass `html` to your email provider (Resend, SendGrid, Nodemailer, etc.)
await sendEmail({
to: "sarah@example.com",
subject: "Welcome!",
html,
});Local preview server
npx react-email devOpens a browser preview at http://localhost:3000 — live-reloads as you edit.
Related packages
Fast, composable command palette for React — keyboard-driven search UI with fuzzy filtering and accessible markup out of the box.
@dnd-kit/coreReactModern, accessible drag-and-drop toolkit for React — fully customizable with keyboard support, collision detection, and zero dependencies.
embla-carousel-reactReactLightweight, extensible carousel library for React — smooth scrolling, touch/mouse drag, and full CSS control without prescribing markup.
flagsReactProvider-agnostic feature flags SDK for Next.js and React — toggle features without redeploying.
framer-motionReactProduction-ready declarative animation library for React — gestures, layout animations, and scroll-driven effects with a clean API.