Build emails from a small set of cross-client-tested components. Import them as React (`@unitpost/email/react`), author visually in the template editor, or write the same tags as a string. Same document, same HTML recipients get.
Email component library that works in Outlook, Gmail, and Apple Mail.
Email component library that works in Outlook, Gmail, and Apple Mail. `@unitpost/email` is the same renderer the send engine uses — preview here is the email recipients get. Author as React components, as a TSX string, or visually in the template editor. All three produce the same document.
React when you want it
`import { Heading, Button, render } from "@unitpost/email/react"` is the react-email-shaped path — types and JSX in your editor. The visual editor and agents use the same tags as a string (`parseTsx`) so the document can round-trip. Neither path is a second renderer.
Style with Tailwind-style `className` (compiled to inline CSS), extra declarations via `custom-css`, or the component props. Recipients get the compiled markup — not a stylesheet they have to load.
Insert dynamic data anywhere with `{{variable}}` — it's substituted at send time from the values you pass to the API, a contact's fields, or a campaign default.
Add the package and render your first email in a few minutes.
You don't need to install anything to use the components in the in-app editor — open any template, switch to Code mode, and start composing. For a coding agent, one Skill command. For your own codebase, the npm package.
Install `@unitpost/email` (plus its `zod` peer dependency) — it ships the component types, the parser, and the same `renderToHtml` renderer the send engine uses. Source: github.com/unitpostcom/email.
In a React app, import the catalog and call `render`. Without React (or in the editor's Code mode), the same tags are a string passed to `parseTsx`.
Node.js
import { Section, Heading, Text, Button, render } from "@unitpost/email/react";
export function Welcome({ name }: { name: string }) {
return (
<Section paddingY={32}>
<Heading level={1}>Welcome, {name}</Heading>
<Text>Thanks for joining. Confirm your email to get started.</Text>
<Button href="https://example.com/verify">Verify email</Button>
</Section>
);
}
const html = render(<Welcome name="Mike" />);
// No React: parseTsx(`<Section>…</Section>`) then renderToHtml(doc).
Prefer the visual builder?
You never have to write code — the template editor builds the identical document with drag-and-drop blocks, and you can flip to Code mode any time to see (or edit) the TSX.
Save the template in your workspace and reference it when you send, or pass the rendered HTML directly. Both go through the same delivery pipeline — see the API reference for the full send surface.
Explore the components below — start with Section and Row for layout, then Heading, Text, and Button for content. Every block also accepts the common props.
Components
Every building block, with a live preview and its props.
Inner content may include inline HTML for formatting: <strong>, <em>, <u>, <a href>, and <span style> (color / background-color). These round-trip through the visual editor.
There's no <Html> tag in code mode — any markup that isn't a known component (e.g. a <table> or <div>) automatically becomes an Html block and is emitted verbatim at render. Content passes through the 3-layer HTML sanitizer (scripts, event handlers, and javascript: URLs are stripped) both on save and at render. {{variables}} interpolate inside the markup. Prefer the built-in components when possible — raw HTML is on you to keep Outlook-safe.
Every block accepts these in addition to its own props.
Prop
Type
Default
Description
margin-bottom
number
16
Vertical space (px) below the block.
className
string
—
Tailwind-style utility classes compiled to inline CSS at render (e.g. "mt-4 text-zinc-500 sm:hidden"). Responsive/pseudo variants are hoisted into a <style> block. `class` and `tw` are accepted as aliases in code.
custom-css
css
—
Extra inline CSS declarations merged onto the block's root element (e.g. "letter-spacing: 1px; opacity: 0.9"). Inlined so it survives every client.
Per-side spacing is also supported via padding and margin objects in the visual editor's inspector.
Pre-built sections from the same components — not a second API. Copy the React example into your app, or insert from the Layouts rail in the editor. Same HTML either way.
Hairline and a friendly help line — the transactional closer. No postal address or unsubscribe (marketing emails get those from the managed compliance footer automatically).
Two-column footer: a short tagline on the left, app/store links on the right. No unsubscribe or postal address — the managed compliance footer adds those automatically.
Playground
Write email code and see the exact HTML our engine produces — live, in your browser, with nothing to install. It renders through the same pipeline the editor's exact preview and the send engine use.