← Back to blog

React Email + Resend: A Production Guide for 2026

Why React Email Is Worth It (And Where It Gets Hard)

React Email is one of the best things to happen to email development in a decade. You write components in React, you get type safety, you can share design tokens with your main app, and the local preview server shows you live updates as you code. For developers who've spent time maintaining raw HTML email templates, the difference is dramatic.

But it's not without friction. Email rendering is still the wild west in 2026. Outlook uses a Word-based rendering engine. Gmail clips long emails. Dark mode inverts things you didn't expect it to invert. React Email gives you better tools, but it doesn't make email rendering problems go away — you just get to debug them with better code.

Here's what to know before you ship your first production template.

Installation and the Right Project Structure

Install with npm install @react-email/components react react-dom. React Email ships its components separately from the renderer (@react-email/render) — install that too, because you'll need it to convert your React components to HTML strings before sending through Resend.

Keep your templates in a dedicated directory, separate from your main app components. src/emails/ works well. Each template is just a React component that returns a <Html> tree. The preview server runs all of them so you can browse and test locally at localhost:3000.

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

export default function WelcomeEmail({ firstName }: { firstName: string }) {
  return (
    <Html>
      <Body style={{ fontFamily: 'sans-serif', backgroundColor: '#ffffff' }}>
        <Container>
          <Text>Hey {firstName},</Text>
          <Text>Welcome to Driplane.</Text>
          <Button href="https://driplane.app/dashboard">
            Get started
          </Button>
        </Container>
      </Body>
    </Html>
  )
}

Simple, readable, maintainable. This is what email templates should look like.

Rendering to HTML for Resend

Resend expects an HTML string, not a React component. Use @react-email/render to convert:

import { render } from '@react-email/render'
import WelcomeEmail from './emails/WelcomeEmail'

const html = await render(<WelcomeEmail firstName="Fathi" />)

Then pass html to resend.emails.send(). Straightforward. The main thing to know: render() is async, so always await it. Forgetting this is a common source of mysterious "blank email" bugs.

The Outlook Problem

Outlook (especially Outlook 2019 and earlier on Windows) uses a Word-based rendering engine that ignores most modern CSS. The main gotchas:

Flexbox and Grid don't work. Use table-based layouts for anything that needs to be multi-column. React Email's <Row> and <Column> components handle this — they render as HTML tables under the hood. Use them instead of CSS-only layouts.

Background images on divs don't render. Outlook strips them. If you need a background image, use a table cell with background attribute and a VML fallback. React Email has a <Body> component that handles background color correctly — stick to solid colors for anything you need to work in Outlook.

Max-width on divs is ignored. Wrap everything in a centered table with a fixed width. The <Container> component from React Email does this correctly by default.

Dark Mode

Dark mode email support is still inconsistent across clients, but the big ones (Apple Mail, iOS Mail) flip light backgrounds to dark and dark text to light. This means if you have a white background with dark text, it looks fine in light mode — but in dark mode on iOS, Apple Mail may invert the colors on just part of your template and create contrast issues.

The safest approach: define explicit dark mode overrides with a <style> block inside your <Head>:

@media (prefers-color-scheme: dark) {
  .email-body { background-color: #1a1a1a !important; }
  .email-text { color: #eeeeee !important; }
}

React Email's preview server shows you light mode. Test dark mode separately by enabling it on your actual device or using a tool like Litmus or Email on Acid before sending to production.

Sending Through Resend

Once you have your HTML string, the Resend send call is straightforward:

await resend.emails.send({
  from: 'Fathi <[email protected]>',
  to: user.email,
  subject: 'Welcome to Driplane',
  html,
})

A few things that bite people: the from address must be on a verified domain in your Resend account. The "Name <email>" format works and shows the display name in the inbox. If you omit the display name, you get just the email address — usually less friendly for marketing emails.

Using React Email Templates in Driplane

Driplane supports React Email templates directly in the sequence builder. You can paste your rendered HTML into the email step, or use Driplane's template selector if you've pre-registered templates. This means you can write your templates in React, preview them locally, and then deploy them into a sequence without copy-pasting HTML every time — the sequence builder becomes the delivery layer and your codebase stays the source of truth for template design.

Ready to build email sequences?

Get Driplane for $47 — one-time payment, lifetime access.

Price increases to $67 soon

Get started now