Building & Exporting
Relevant source files
The following files were used as context for generating this wiki page:
Building and Exporting refers to the transformation of React components into production-ready email formats, such as HTML and plain text. This process bridges the gap between a modern developer workflow using TypeScript and React and the archaic requirements of various email clients.
The system utilizes esbuild for rapid bundling of templates and a specialized rendering pipeline to ensure that styles are inlined and compatibility is maintained across clients like Gmail, Outlook, and Apple Mail. You can perform these actions via the Command Line Interface (CLI) or programmatically within the Email Editor.
CLI Commands and Operations
The react-email CLI provides the primary interface for managing template development and final output generation.
| Command | Purpose |
|---|---|
email dev | Starts a local development server at localhost:3000 with hot-reloading. |
email build | Builds the preview app for production deployment. |
email export | Generates static HTML and plain text files from templates into an output directory. |
Sources: packages/react-email/readme.md:37-52, skills/react-email/SKILL.md:214-222
The dev and build Workflow
The dev command watches your email directory (defaulting to ./emails) and rebuilds templates automatically using esbuild. You can pass a --esbuild-plugins flag to include custom compilation transforms. The build command prepares the preview application for deployment by bundling the templates and the preview UI.
Sources: packages/react-email/readme.md:41-47, skills/react-email/SKILL.md:214-222
The export Workflow
The export command transforms every template in your directory into a standalone file. It clears the target output directory before processing to ensure no stale artifacts remain.
- Template Discovery: The CLI recursively searches the email directory for all valid template files.
- Bundling: The system bundles templates into CommonJS (
.cjs) modules usingesbuild. - Batch Rendering: The CLI renders these modules into HTML or text files using worker threads to manage memory and performance.
- Static Assets: If a
staticdirectory exists within your emails folder, the CLI copies its contents to the output directory.
Sources: packages/react-email/src/cli/commands/export.ts:114-116, packages/react-email/src/cli/commands/export.ts:213-233
Technical Architecture of the Export Pipeline
The export process is optimized for large template sets by using batching and worker threads.
The diagram shows the sequential stages of the export command, highlighting the batching mechanisms used for bundling and rendering.
Bundling Logic
The CLI uses esbuild to bundle React templates. It uses specific configurations to ensure templates run correctly in a Node.js environment during the rendering phase.
- Batching: Templates are bundled in groups (default
BUILD_BATCH_SIZE = 10) so that theesbuilddependency graph does not overwhelm system memory. - Format: Templates are bundled as
cjs(CommonJS) to allow dynamic requirement in worker threads. - Loaders: The system explicitly handles
.jsfiles as JSX and inlines CSS via a custominlineCssLoader.
Sources: packages/react-email/src/cli/commands/export.ts:41, packages/react-email/src/cli/commands/export.ts:121-140
Worker Thread Rendering
To prevent require.cache from holding onto large React bundles and causing memory leaks, the CLI renders templates inside Node.js Worker threads.
- Isolation: Each batch (default
RENDER_BATCH_SIZE = 25) runs in a fresh V8 isolate. - Progress Tracking: The worker communicates progress back to the main process via
parentPort.postMessage. - Cleanup: The temporary
.cjsfiles generated during the bundle phase are unlinked (deleted) after the HTML is successfully written.
Sources: packages/react-email/src/cli/commands/export.ts:45-72, packages/react-email/src/cli/commands/export.ts:175-207
Programmatic Rendering and Serialization
Beyond the CLI, components can be rendered to HTML programmatically for use in APIs or the visual editor.
The render Function
The core rendering utility takes a React component and options to produce string output.
import { render } from 'react-email';
import { MyEmail } from './emails/MyEmail';
// Render to HTML
const html = await render(<MyEmail />);
// Render to Plain Text
const text = await render(<MyEmail />, { plainText: true });
Sources: skills/react-email/SKILL.md:180-192
Serialization in the Editor
The @react-email/editor package uses composeReactEmail to serialize its internal TipTap JSON state into email-ready code.
This sequence shows how the editor serializes its content by traversing custom nodes and applying theming before final rendering.
- Traversal: The serializer traverses every node and mark in the editor's document.
- Node Rendering: Each custom
EmailNodeimplementsrenderToReactEmail(), returning standard React Email components. - Theming: The
EmailThemingplugin applies visual hierarchy (typography, spacing) as inline styles. - Format Options: The output includes both a prettified HTML version and an
unformattedHtmlversion which lacks Prettier indentation artifacts.
Sources: packages/editor/src/core/serializer/compose-react-email.spec.tsx:288-305, skills/react-email/references/EDITOR.md:200-218
Building for Production
When you prepare templates for a production environment, you must handle static assets using absolute URLs. While the dev server serves files from the /static folder locally, production requires a CDN or public hosting URL.
const baseURL = process.env.NODE_ENV === "production"
? "https://cdn.example.com"
: "";
<Img src={`${baseURL}/static/logo.png`} />
Sources: skills/react-email/SKILL.md:143-157
Summary
Building and exporting in React Email transforms high-level React code into optimized, table-based HTML. The CLI manages this through a robust pipeline of esbuild bundling and worker-thread rendering, while the @react-email/editor provides programmatic hooks to generate the same output from a visual interface. The process ensures that styles are inlined, static assets are correctly referenced, and performance is maintained even with hundreds of templates.