@better-email/react-email
v0.1.0
Published
Build Better Email Design System trees from existing React Email projects.
Readme
@better-email/react-email
Turn an existing React Email project into a Better Email Design System file
tree. Keep authoring ordinary React components; the adapter adds stable Module
metadata and emits the files that better ds push can ship.
Setup
Install the adapter alongside React and React Email's renderer:
pnpm add -D @better-email/react-email @react-email/render@^2Add better.react-email.config.mjs:
export default {
modules: "src/modules/**/*.{tsx,jsx}",
designSystemDir: "better-src",
out: "better",
};Those values are the defaults. better-react-email init creates the config,
a minimal version 3 Design System base, and an example Module without
overwriting existing files.
Modules
Default-export the component and export its Better Email metadata as better:
import { Section, Text } from "@react-email/components";
import { liquid } from "@better-email/react-email";
import type { BetterModule } from "@better-email/react-email";
export const better = {
key: "hero",
name: "Hero",
settings: [
{
key: "hero",
name: "Hero",
inputs: [{ key: "heading", name: "Heading", type: "text" }],
},
],
} satisfies BetterModule;
export default function Hero() {
return (
<Section>
<Text>{liquid("hero.heading")}</Text>
</Section>
);
}liquid("hero.heading") becomes the literal {{ hero.heading }} placeholder in
the built Module. Use liquidTag("if hero.enabled") for
{% if hero.enabled %} and its matching closing tag for control flow. The
helpers emit an HTML-safe marker while React renders, which prevents React from
escaping Liquid operators; a standalone React Email development preview shows
that marker text until better-react-email build restores the Liquid syntax.
Module, setting, and input IDs are optional. Missing IDs become
re_<moduleKey>, re_<moduleKey>_<settingKey>, and
re_<moduleKey>_<settingKey>_<inputKey>; explicit IDs are preserved when
adopting an existing Module.
React Email inlines component styles. The adapter extracts only the rendered
body, so styles emitted into a document head by Tailwind do not become part of
the Module fragment. Put responsive and dark-mode rules in
better-src/base.liquid.
Build
better ds pull <id> --dir better
better-react-email build
(cd better && better check && better ds push)The complete output tree is validated with the same serializer as
better push before anything is written. The neutral
better/.better-adapter-manifest.json tracks generated Modules; pulled and
hand-maintained Modules survive, and better/.better/ stays untouched.
Publishing
pnpm run build:react-email-package
npm publish dist/react-email-package --access public