# @suaveplan/email-templates - Universal React-free email template engine: VNode factories, nine reusable components, five built-in templates (welcome, verification, password-reset, notification, invoice), typed registry, fluent builder, theme system, structured errors, OTel instruments. Produces email-safe HTML strings with inline styles; runs in Bun, Node, and browser. Universal, React-free email template engine. Produces email-safe HTML strings with inline styles via VNode factories — runs identically in Bun, Node, and the browser. ## Documentation tree - [email-button](./src/components/email-button/email-button.md) — `EmailButton` is the canonical call-to-action surface in an email body — a table-wrapped `` with variant-driven them… - [email-button](./src/components/email-button/email-button.md) — `EmailButton` is the canonical call-to-action surface in an email body — a table-wrapped `` with variant-driven them… - [email-container](./src/components/email-container/email-container.md) — `EmailContainer` groups related content inside an email body — a callout box, an info banner, a code-card. It emits a s… - [email-container](./src/components/email-container/email-container.md) — `EmailContainer` groups related content inside an email body — a callout box, an info banner, a code-card. It emits a s… - [email-divider](./src/components/email-divider/email-divider.md) — A horizontal divider rendered as a single-row `` whose `
` carries `border-top: 1px solid `. The table… - [email-divider](./src/components/email-divider/email-divider.md) — A horizontal divider rendered as a single-row `` whose `
` carries `border-top: 1px solid `. The table… - [email-footer](./src/components/email-footer/email-footer.md) — Renders the email footer block — company copyright, optional address, optional list of inline links (typically Privacy… - [email-footer](./src/components/email-footer/email-footer.md) — Renders the email footer block — company copyright, optional address, optional list of inline links (typically Privacy… - [email-heading](./src/components/email-heading/email-heading.md) — Renders an `

`…`

` element with a level-keyed font-size and line-height schedule tuned for inbox-rendering ergono… - [email-heading](./src/components/email-heading/email-heading.md) — Renders an `

`…`

` element with a level-keyed font-size and line-height schedule tuned for inbox-rendering ergono… - [email-image](./src/components/email-image/email-image.md) — Renders an `` inside a centring `` with the canonical responsive-email defaults (`display:block`, `max-widt… - [email-image](./src/components/email-image/email-image.md) — Renders an `` inside a centring `
` with the canonical responsive-email defaults (`display:block`, `max-widt… - [email-layout](./src/components/email-layout/email-layout.md) — `EmailLayout` is the root VNode every email template wraps its body in. It emits a 100%-width `
` with a themed m… - [email-layout](./src/components/email-layout/email-layout.md) — `EmailLayout` is the root VNode every email template wraps its body in. It emits a 100%-width `
` with a themed m… - [email-link](./src/components/email-link/email-link.md) — Themed inline `` link with safe defaults (`target="_blank"`, `rel="noopener noreferrer"`) for body-copy hyperlinks.… - [email-link](./src/components/email-link/email-link.md) — Themed inline `` link with safe defaults (`target="_blank"`, `rel="noopener noreferrer"`) for body-copy hyperlinks.… - [email-text](./src/components/email-text/email-text.md) — Paragraph component for email-body copy. `EmailText` emits a themed `

` with one of three size variants (`body` / `ca… - [email-text](./src/components/email-text/email-text.md) — Paragraph component for email-body copy. `EmailText` emits a themed `

` with one of three size variants (`body` / `ca… - [error-codes](./src/error-codes/error-codes.md) — Stable error-code registry for `@suaveplan/email-templates`. Every failure raised by the package extends `SuaveplanErro… - [error-codes](./src/error-codes/error-codes.md) — Stable error-code registry for `@suaveplan/email-templates`. Every failure raised by the package extends `SuaveplanErro… - [message](./src/message/message.md) — `createEmailMessage` glues the renderer to the addressing envelope, producing an `EmailMessageResult` plain object suit… - [message](./src/message/message.md) — `createEmailMessage` glues the renderer to the addressing envelope, producing an `EmailMessageResult` plain object suit… - [renderer](./src/renderer/renderer.md) — The renderer is the bridge between the `EmailTemplate` contract and a final `{ html, text, subject }` triple re… - [renderer](./src/renderer/renderer.md) — The renderer is the bridge between the `EmailTemplate` contract and a final `{ html, text, subject }` triple re… - [telemetry](./src/telemetry/telemetry.md) — Exposes the OpenTelemetry instrument set published by `@suaveplan/email-templates`. Every public render or registry mut… - [telemetry](./src/telemetry/telemetry.md) — Exposes the OpenTelemetry instrument set published by `@suaveplan/email-templates`. Every public render or registry mut… - [template-builder](./src/template-builder/template-builder.md) — `TemplateBuilder` is a fluent API for assembling an `EmailTemplate` value step-by-step. It exists because const… - [template-builder](./src/template-builder/template-builder.md) — `TemplateBuilder` is a fluent API for assembling an `EmailTemplate` value step-by-step. It exists because const… - [template-registry](./src/template-registry/template-registry.md) — `TemplateRegistry` is a type-safe in-memory store for `EmailTemplate` values keyed by name. It supports per-name lookup… - [template-registry](./src/template-registry/template-registry.md) — `TemplateRegistry` is a type-safe in-memory store for `EmailTemplate` values keyed by name. It supports per-name lookup… - [invoice](./src/templates/invoice/invoice.md) — The `invoiceTemplate` is the receipt / invoice / order-confirmation email. It renders a heading carrying the invoice nu… - [invoice](./src/templates/invoice/invoice.md) — The `invoiceTemplate` is the receipt / invoice / order-confirmation email. It renders a heading carrying the invoice nu… - [notification](./src/templates/notification/notification.md) — The `notificationTemplate` is the generic system-notification email — a configurable severity callout suitable for prod… - [notification](./src/templates/notification/notification.md) — The `notificationTemplate` is the generic system-notification email — a configurable severity callout suitable for prod… - [password-reset](./src/templates/password-reset/password-reset.md) — The `passwordResetTemplate` is the canonical password-reset message. It explains the request, exposes a reset CTA, comm… - [password-reset](./src/templates/password-reset/password-reset.md) — The `passwordResetTemplate` is the canonical password-reset message. It explains the request, exposes a reset CTA, comm… - [verification](./src/templates/verification/verification.md) — The `verificationTemplate` is the standard email-address verification flow message. It greets the recipient, optionally… - [verification](./src/templates/verification/verification.md) — The `verificationTemplate` is the standard email-address verification flow message. It greets the recipient, optionally… - [welcome](./src/templates/welcome/welcome.md) — The `welcomeTemplate` is the canonical post-signup onboarding email. It greets the recipient by name, summarises why th… - [welcome](./src/templates/welcome/welcome.md) — The `welcomeTemplate` is the canonical post-signup onboarding email. It greets the recipient by name, summarises why th… - [theme](./src/theme/theme.md) — Provides the theme tokens consumed by every email component — colours, typography, spacing, branding, border-radius, an… - [theme](./src/theme/theme.md) — Provides the theme tokens consumed by every email component — colours, typography, spacing, branding, border-radius, an… - [vnode](./src/vnode/vnode.md) — Defines the universal VNode primitive — a `{ tag, attrs, children }` triple plus a pure-string HTML renderer — tha… - [vnode](./src/vnode/vnode.md) — Defines the universal VNode primitive — a `{ tag, attrs, children }` triple plus a pure-string HTML renderer — tha… ## What's included - **Nine reusable components** — `EmailLayout`, `EmailContainer`, `EmailHeading`, `EmailText`, `EmailLink`, `EmailImage`, `EmailDivider`, `EmailButton`, `EmailFooter`. - **Five built-in templates** — `welcomeTemplate`, `verificationTemplate`, `passwordResetTemplate`, `notificationTemplate`, `invoiceTemplate`. - **VNode core** — `h(tag, attrs, children)` hyperscript factory and a pure-string `renderVNode` walker. - **Renderer** — `renderToHtml(template, props, options?)` → `{ html, text, subject }` with OTel instrumentation. - **Theme system** — `defaultTheme`, `createTheme`, `mergeThemes`. - **Type-safe registry** — `TemplateRegistry` with category / tag / author search. - **Fluent builder** — `TemplateBuilder` / `createTemplateBuilder()`. - **Adapter** — `createEmailMessage(template, props, recipient, options?)` returning a plain-object envelope ready for SMTP / SES / SendGrid. - **Structured errors** — `EmailTemplatesError` with six `EMAIL_TEMPLATES.*` codes. ## Quick start ```ts import { createEmailMessage, welcomeTemplate, } from "@suaveplan/email-templates"; const message = createEmailMessage( welcomeTemplate, { recipientName: "Jane", ctaUrl: "https://app.example.test/get-started" }, { to: "jane@example.test", from: "hello@suaveplan.com" }, ); await mailer.send(message); ``` ## Architecture Upstream `@suaveplan/email-templates` was a React component library rendered via `react-dom/server`. The port honours the enterprise spec §3 ("Zero browser / Node / React dependencies") by re-implementing the full upstream surface as **VNode factories** — pure functions returning `{ tag, attrs, children }` triples walked by a single HTML-emitter (`renderVNode`). The renderer is the sole point at which child text is HTML-escaped and attributes are serialised. Components emit data; escaping happens once. ## Universal - Zero React / DOM / Node-specific dependencies at runtime. - Injectable `Clock` (`@suaveplan/types`) for deterministic footer year. - OTel instruments via `@opentelemetry/api`. - Pure-TypeScript implementation, 100% statement / branch / function / line coverage. ## Sub-path exports `@suaveplan/email-templates/vnode`, `…/theme`, `…/renderer`, `…/message`, `…/template-builder`, `…/template-registry`, `…/components`, `…/templates`, `…/errors`, `…/otel` — each exposes a focused slice of the surface for tree-shake friendliness.