Context
PR #4766 (move mjml to optional peer dep in @vendure/email-plugin) was closed in favour of a fuller plan: deprecate HandlebarsMjmlGenerator and ship React Email (@react-email/render + @react-email/components) as the new default generator. Full rationale (worm-threat model favours dep-count, MJML DX showing its age, half-measure vs full replacement) is in the closing comment, tracked under #4761.
Planned sequence for the generator change:
- v3.7: Add
ReactEmailGenerator alongside HandlebarsMjmlGenerator. Ship Vendure's default templates in JSX form. Mark HandlebarsMjmlGenerator as @deprecated and add a migration guide.
- v3.8 / v4.0: Switch default to
ReactEmailGenerator. mjml becomes an optional peer dependency.
- v4.x: Remove
HandlebarsMjmlGenerator entirely.
Why this issue
If we're already opening up @vendure/email-plugin in v3.7 — touching the generator API, default templates, docs, and the user-facing surface — it's a good moment to consider what else this plugin should be doing in a modern admin/dashboard context. The plugin has barely changed shape since it was first shipped, while the platform around it (notably the new React Dashboard) has moved on considerably.
The goal of this issue is to scope and decide which of the following ship in v3.7 alongside the React Email work.
Ideas to discuss
1. Dashboard Views
The new React Dashboard makes it cheap to add first-class views for plugins. The email plugin has plenty of surface that would benefit:
- Templates view — list configured
EmailEventHandlers, the events they listen to, the resolved template(s), and whether each is currently enabled per-channel.
- Preview view — render a template against realistic sample data (Order, Customer, etc.) and view the resulting HTML and subject inline, without having to trigger the actual event. Hot-reload on template edits in dev mode.
- Settings view — surface plugin config (transport, from address, attachment limits) read-only, with copy-paste examples for editing in code.
Open questions:
- Where do Dashboard Views for core plugins live — in the plugin package itself, or under
@vendure/dashboard?
- Permissions model — new
ReadEmailTemplates permission, or piggyback on ReadSettings?
- Read-only vs editable templates (the latter would imply runtime template overrides, which is a much bigger feature).
2. Email delivery log
Today the plugin emits to a configurable transport (SMTP, SES, file, etc.) and that's it. There's no built-in record of what was sent, to whom, at what time, with what outcome.
A persisted delivery log would give:
- An admin a way to confirm "did the customer receive the order confirmation?" without diving into transport-level logs.
- Support teams a self-serve way to resend a failed email.
- A natural foundation for retries, bounce handling, and suppression lists in future.
Open questions:
- Storage model —
EmailDeliveryLog entity in @vendure/email-plugin, opt-in via config? Retention policy? Channel-scoped?
- Fields — recipients, subject, template name, event type, status (queued / sent / failed / bounced), timestamps, transport response payload?
- API — admin GraphQL extension, paginated list + filters,
resendEmail mutation?
- Dashboard View to consume it (overlaps with item 1).
3. Dev Mailbox built into dashboard
In development we currently default to the file transport, which writes a .json per email to disk. It works, but the DX is fiddly — most devs end up running mailpit / mailhog / maildev in Docker just to inspect what their templates rendered to.
If the dashboard exposed a Dev Mailbox view backed by the file transport (or a new in-memory / SQLite-backed dev transport), the framework would ship a working "see your emails" experience out of the box. No extra container, no extra port, no extra docs page.
Open questions:
- Reuse the existing file transport as the data source, or ship a dedicated
DevMailboxTransport that backs the view directly?
- Auto-enable when
NODE_ENV !== 'production', or always opt-in?
- Live updates (WebSocket / polling) when a new email arrives?
- Is this just the delivery-log view (item 2) plus a development-mode flag, or a distinct feature?
Scope decision
Each of the three above is independent and could ship without the others, but they share infrastructure (Dashboard View pattern, delivery-log entity, transport contract). Worth agreeing the dependency order before parallelising:
- A Dashboard View is a prerequisite for the other two having any UI surface.
- The delivery log gives the Dev Mailbox most of its data model for free.
- The Dev Mailbox is the highest-leverage DX win and could be carved out and shipped on its own once the dashboard-view pattern + transport contract are settled.
Realistic v3.7 cut might be: React Email migration + a Templates / Preview Dashboard View + the delivery-log entity (without the resend mutation), with the Dev Mailbox following as a v3.8 follow-up. To be discussed.
Related
Context
PR #4766 (move
mjmlto optional peer dep in@vendure/email-plugin) was closed in favour of a fuller plan: deprecateHandlebarsMjmlGeneratorand ship React Email (@react-email/render+@react-email/components) as the new default generator. Full rationale (worm-threat model favours dep-count, MJML DX showing its age, half-measure vs full replacement) is in the closing comment, tracked under #4761.Planned sequence for the generator change:
ReactEmailGeneratoralongsideHandlebarsMjmlGenerator. Ship Vendure's default templates in JSX form. MarkHandlebarsMjmlGeneratoras@deprecatedand add a migration guide.ReactEmailGenerator.mjmlbecomes an optional peer dependency.HandlebarsMjmlGeneratorentirely.Why this issue
If we're already opening up
@vendure/email-pluginin v3.7 — touching the generator API, default templates, docs, and the user-facing surface — it's a good moment to consider what else this plugin should be doing in a modern admin/dashboard context. The plugin has barely changed shape since it was first shipped, while the platform around it (notably the new React Dashboard) has moved on considerably.The goal of this issue is to scope and decide which of the following ship in v3.7 alongside the React Email work.
Ideas to discuss
1. Dashboard Views
The new React Dashboard makes it cheap to add first-class views for plugins. The email plugin has plenty of surface that would benefit:
EmailEventHandlers, the events they listen to, the resolved template(s), and whether each is currently enabled per-channel.Open questions:
@vendure/dashboard?ReadEmailTemplatespermission, or piggyback onReadSettings?2. Email delivery log
Today the plugin emits to a configurable transport (SMTP, SES, file, etc.) and that's it. There's no built-in record of what was sent, to whom, at what time, with what outcome.
A persisted delivery log would give:
Open questions:
EmailDeliveryLogentity in@vendure/email-plugin, opt-in via config? Retention policy? Channel-scoped?resendEmailmutation?3. Dev Mailbox built into dashboard
In development we currently default to the file transport, which writes a
.jsonper email to disk. It works, but the DX is fiddly — most devs end up runningmailpit/mailhog/maildevin Docker just to inspect what their templates rendered to.If the dashboard exposed a Dev Mailbox view backed by the file transport (or a new in-memory / SQLite-backed dev transport), the framework would ship a working "see your emails" experience out of the box. No extra container, no extra port, no extra docs page.
Open questions:
DevMailboxTransportthat backs the view directly?NODE_ENV !== 'production', or always opt-in?Scope decision
Each of the three above is independent and could ship without the others, but they share infrastructure (Dashboard View pattern, delivery-log entity, transport contract). Worth agreeing the dependency order before parallelising:
Realistic v3.7 cut might be: React Email migration + a Templates / Preview Dashboard View + the delivery-log entity (without the resend mutation), with the Dev Mailbox following as a v3.8 follow-up. To be discussed.
Related