Openui langExamples

React Email

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 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 →

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:

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:

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 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:
cd examples/react-email
pnpm install
  1. Create a .env.local file with your API key:
OPENAI_API_KEY=sk-...
  1. Start the dev server:
pnpm dev

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

On this page