Sep 20, 2026 ยท 10 min read

React Email + Tailwind CSS: Complete Developer Guide

Build React Email templates with Tailwind CSS, typed props, reusable components, HTML rendering, provider integration, and cross-client testing.

React Email + Tailwind CSS: Complete Developer Guide

React Email and Tailwind CSS give TypeScript teams a component-based way to author transactional email. React describes the message structure, Tailwind supplies utility styling, and the render step produces HTML that your provider can send.

The important boundary is the same as any email workflow: React and Tailwind run during development or server-side rendering. The recipient receives HTML and plain text not React, JavaScript, or a Tailwind runtime.

Install React Email

Follow the current React Email setup for your package manager, then keep templates in a dedicated directory such as emails/.

A useful structure is:

emails/
  components/
    EmailButton.tsx
    EmailFooter.tsx
    EmailLayout.tsx
  fixtures/
    welcome.ts
  WelcomeEmail.tsx

Keep email components separate from web UI. They can share types, formatting functions, and design tokens, but email markup has different compatibility constraints.

Build a Tailwind-styled component

import {
  Body,
  Button,
  Container,
  Head,
  Heading,
  Html,
  Preview,
  Section,
  Tailwind,
  Text,
} from 'react-email';

type WelcomeEmailProps = {
  firstName: string;
  dashboardUrl: string;
};

export function WelcomeEmail({
  firstName,
  dashboardUrl,
}: WelcomeEmailProps) {
  return (
    <Html lang="en">
      <Head />
      <Preview>Your workspace is ready</Preview>
      <Tailwind>
        <Body className="m-0 bg-slate-100 font-sans text-slate-900">
          <Container className="mx-auto max-w-[600px] px-5 py-10">
            <Section className="rounded-xl bg-white px-8 py-10">
              <Text className="m-0 text-sm font-semibold text-blue-700">
                Welcome aboard
              </Text>
              <Heading className="mt-3 mb-0 text-3xl font-bold leading-tight">
                Hi {firstName}, your workspace is ready
              </Heading>
              <Text className="mt-5 mb-0 text-base leading-7 text-slate-600">
                Create your first project and invite your team.
              </Text>
              <Button
                href={dashboardUrl}
                className="mt-7 rounded-lg bg-blue-600 px-6 py-3 font-semibold text-white no-underline"
              >
                Open dashboard
              </Button>
            </Section>
          </Container>
        </Body>
      </Tailwind>
    </Html>
  );
}

Use email primitives for document structure and ordinary complete Tailwind classes for styling. Avoid dynamically assembling utilities because Tailwind must see full class tokens.

Why use the Tailwind wrapper?

The React Email Tailwind component processes utility classes for the email render. It provides a familiar styling model while keeping the template within React Email's primitives.

That does not make every web utility safe. Complex Grid, positioning, transforms, and JavaScript interactions still conflict with email-client limitations. Prefer colors, typography, spacing, widths, borders, and simple layout patterns.

Read what actually works with Tailwind in email.

Define typed template props

Treat props as the public contract of the message:

type InvoiceEmailProps = {
  customerName: string;
  invoiceNumber: string;
  totalFormatted: string;
  dueDateFormatted: string;
  invoiceUrl: string;
};

Pass display-ready values instead of database models. This keeps currency, date, and localization decisions in application services where they can be tested independently.

Provide fixture props for preview and automated tests. Include long names, missing optional sections, translated content, and large amounts.

Create email-specific components

Extract a component when it owns compatibility or a repeated design decision not merely because JSX is longer than a web component.

Strong candidates include:

  • document layout and preheader;
  • constrained container;
  • bulletproof button;
  • logo header;
  • receipt table;
  • divider;
  • support block; and
  • compliance footer.

Keep the component API small. A button usually needs href, children, and a limited visual variant. Passing arbitrary class strings everywhere weakens the design system.

Render HTML and plain text

Use React Email's render utility in a pure function that returns subject, HTML, and text:

import { render } from '@react-email/render';

export async function renderWelcomeEmail(props: WelcomeEmailProps) {
  const component = <WelcomeEmail {...props} />;

  return {
    subject: `Welcome, ${props.firstName}`,
    html: await render(component),
    text: await render(component, { plainText: true }),
  };
}

Await rendering before calling the provider. Validate that both outputs are non-empty and that required links remain present.

Send through any provider

Keep transport outside the component:

const message = await renderWelcomeEmail(data);

await transport.send({
  to: user.email,
  from: '[email protected]',
  subject: message.subject,
  html: message.html,
  text: message.text,
});

This separation makes provider migrations, previews, tests, and queued delivery much easier.

Responsive React Email

Start with a single-column mobile-friendly default. Breakpoint utilities need retained media queries and client testing.

Avoid making a critical action depend on hidden, sm:block, or a complex reordering rule. Responsive styles should adjust spacing, type, and optional column behavior.

Use the responsive Tailwind email guide for safe patterns.

Dark mode

Dark-mode utilities can generate prefers-color-scheme rules, but clients may apply their own automatic transformations or ignore your overrides.

Define explicit light-mode colors, add dark mode as an enhancement, and verify logos, borders, muted text, and CTA contrast. Never assume the browser preview predicts Gmail or Outlook.

See Tailwind email dark mode.

Test templates at four levels

  1. Type and data tests: required props, formatting, and URLs.
  2. Structural tests: heading hierarchy, preheader, alt text, links, and prohibited elements.
  3. Rendered fixtures: focused snapshots for shared components.
  4. Inbox tests: Gmail, Outlook, Apple Mail, and mobile.

Snapshot the rendered artifact, not React's internal tree. Keep snapshots small enough for reviewers to understand meaningful changes.

Common problems

Tailwind classes are missing

Use complete static class names. Confirm the template is inside the source paths scanned by the Tailwind integration.

The email looks right in preview but wrong in Outlook

Preview is browser rendering. Simplify the layout, use email primitives, and inspect the rendered HTML for table fallbacks and unsupported CSS.

The render function returns a promise

Await it. Do not pass an unresolved value or an empty placeholder to the provider.

Web components do not work

Web components may depend on scripts and browser CSS. Rebuild them with React Email primitives while sharing only safe tokens and formatting logic.

Frequently asked questions

Does React Email support Tailwind CSS?

Yes. React Email provides a Tailwind wrapper for utility-class styling. Email-client support still depends on the generated CSS and markup.

Can I use my Tailwind configuration?

Use the configuration mechanisms supported by your installed React Email version and keep values email-friendly. Test custom colors, spacing, and fonts in rendered output.

Does React Email inline all CSS?

Inspect the rendered output. Base styles and conditional CSS have different needs; responsive and dark-mode rules cannot simply become unconditional inline declarations.

Can React Email templates be used outside Resend?

Yes. Render HTML and plain text, then send them through any provider or SMTP transport.

React Email or TailwindMail?

Choose React Email when components belong in a React/TypeScript codebase. Choose TailwindMail when you want Tailwind source plus a visual editor and email-safe export. Compare all three approaches in React Email vs. MJML vs. TailwindMail.

Keep components modern and output conservative

React Email and Tailwind improve source quality: typed props, reusable components, familiar utilities, and fast previews.

Use those tools to generate straightforward email HTML, then test the rendered artifact. Modern authoring and conservative output are complementary, not contradictory.

Share with friends

Ready to ship email-safe HTML?

Start with Tailwind markup, compile to clean HTML, and always preview or send a test before campaigns.