Skip to content

Instantly share code, notes, and snippets.

@mortenson
Last active April 3, 2026 17:35
Show Gist options
  • Select an option

  • Save mortenson/4e7f3839f6a53814ad08cde382120962 to your computer and use it in GitHub Desktop.

Select an option

Save mortenson/4e7f3839f6a53814ad08cde382120962 to your computer and use it in GitHub Desktop.
Render all React Email (react-email) emails to dist
import { render, pretty, toPlainText } from "@react-email/render";
import React from "react";
import fs from "fs/promises";
import path from "path";
import { fileURLToPath } from 'url';
/*
This script will take all emails from the `emails` directory and render them to dist.
For example, given an email component `emails/welcome.tsx` with a single and default export, this would output:
- dist/emails/welcome.html
- dist/emails/welcome.txt
This is especially useful if you don't want to run React on your server, and instead want to replace placeholders
in the static output from this script.
*/
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const dirPath = path.join(__dirname, './emails');
async function loadAllEmails(): Promise<Record<string, React.ComponentType>> {
const files = await fs.readdir(dirPath);
const modules: Record<string, React.ComponentType> = {};
for (const file of files) {
const moduleName = path.parse(file).name;
const fullPath = path.join(dirPath, file);
const module = await import(`file://${fullPath}`);
modules[moduleName] = module.default;
}
return modules;
}
const emails = await loadAllEmails()
type RenderResult = {
id: string;
html: string;
plain: string;
};
const output: RenderResult[] = await Promise.all(
Object.entries(emails).map(async ([id, component]) => {
const html = await pretty(await render(React.createElement(component)));
const plain = toPlainText(html);
return {
id,
html,
plain,
};
}),
);
await fs.mkdir("./dist/emails", { recursive: true });
await Promise.all(
output.map(async (result) => {
const p1 = fs.writeFile(`./dist/emails/${result.id}.html`, result.html);
const p2 = fs.writeFile(`./dist/emails/${result.id}.txt`, result.plain);
return Promise.all([p1, p2]);
}),
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment