---
title: React Email
description: An AI-powered email generator that uses OpenUI Lang to render 44 React Email components from natural language descriptions.
---

OpenUI Lang isn't limited to chat interfaces — it can power any domain-specific UI generator. This example uses [React Email](https://react.email) components as the rendering target, letting users describe emails in plain English and see them rendered live. The `@openuidev/react-email` package ships 44 email components built with `defineComponent`, a ready-to-use `emailLibrary`, and a system prompt with examples and design rules — so the LLM generates well-structured, email-client-compatible HTML out of the box.

[View source on GitHub →](https://github.com/thesysdev/openui/tree/main/examples/react-email)

<div className="bg-[rgba(0,0,0,0.05)] dark:bg-gray-900 rounded-2xl h-[500px] flex p-2">
  <video
    src="/videos/react-email.mp4"
    noControls
    playsInline
    muted
    preload="metadata"
    className="w-full rounded-lg m-auto"
    autoPlay
    loop
  />
</div>

## Building an email library with OpenUI Lang

Each email component wraps a React Email primitive with inline styles (required by email clients that strip `<style>` tags). Here's a simplified example:

```tsx
const EmailButton = defineComponent({
  name: "EmailButton",
  props: z.object({
    label: z.string(),
    href: z.string(),
    backgroundColor: z.string().optional(),
  }),
  description: "Email call-to-action button with link.",
  component: ({ props }) => (
    <Button
      href={props.href as string}
      style={{
        backgroundColor: (props.backgroundColor as string) ?? "#5F51E8",
        color: "#ffffff",
        borderRadius: "6px",
        padding: "12px 24px",
      }}
    >
      {props.label as string}
    </Button>
  ),
});
```

All 44 components are assembled into `emailLibrary` via `createLibrary`. Consumers import the library and prompt options — individual components are internal:

```tsx
import { emailLibrary, emailPromptOptions } from "@openuidev/react-email";

// Generate the system prompt (includes examples + design rules)
const systemPrompt = emailLibrary.prompt(emailPromptOptions);

// Render streamed OpenUI Lang into email components
<Renderer response={openuiCode} library={emailLibrary} isStreaming={isStreaming} />;
```

Once streaming completes, the `useEmailRendering` hook calls `render()` from `@react-email/render` with `{ pretty: true }` client-side to produce formatted HTML for the "Copy HTML" button.

See [Defining Components](/docs/openui-lang/defining-components) for the full `defineComponent` API.

## Architecture

```
Browser (email editor) -- POST /api/chat --> Next.js route --> OpenAI
                        <-- SSE stream --                       (OpenUI Lang)
```

The client sends a conversation to `/api/chat`. The API route loads a pre-generated `system-prompt.txt` (built from `emailLibrary.prompt(emailPromptOptions)`), forwards messages to the LLM with streaming, and returns SSE events. On the client, `emailLibrary` maps each OpenUI Lang node to a React Email component that renders progressively as tokens arrive.

The key difference from other examples: the output isn't interactive UI — it's static email content. The split-view editor shows a live preview on the right and formatted HTML on the left, with copy buttons for both the HTML and the subject line.

## Project layout

```
examples/react-email/
|- src/app/                 # Next.js app (layout, page, API route)
|- src/components/
|  |- composePage/          # Landing page with conversation starters
|  |- emailEditor/          # Split view (top bar, HTML panel, preview, input)
|  |- loadingDots.tsx       # Loading animation (shared)
|  |- session.ts            # Session persistence (shared)
|- src/hooks/               # Theme, clipboard, auto-scroll, email rendering
|- src/generated/           # Auto-generated system prompt

packages/react-email/
|- src/components/          # 44 email components (defineComponent)
|- src/index.ts             # Library, groups, examples, rules
|- src/unions.ts            # Component type unions
```

## Run the example

Run these commands from `examples/react-email`.

1. Install dependencies:

```bash
cd examples/react-email
pnpm install
```

2. Create a `.env.local` file with your API key:

```bash
OPENAI_API_KEY=sk-...
```

3. Start the dev server:

```bash
pnpm dev
```

This auto-generates the system prompt from the email component library and starts the Next.js dev server.
