Developer Tools

Email frameworks compared

Code-first email frameworks for developers, by language: React, Vue, Svelte, MJML, Go, Rust, Python, Ruby, Elixir, Java. Pick one for every inbox.

Olivier Bazoud
November 5, 2026
7 min read

As a developer, you want one email that looks right in every inbox: Gmail, Outlook, Apple Mail, Yahoo Mail, on a desktop and on a phone. Email clients do not share a rendering engine. Each one supports its own subset of HTML and CSS. Outlook on Windows goes further: it renders HTML with the Microsoft Word engine and needs VML for advanced styling. The email client compatibility notes of Inky, the templating language behind Foundation for Emails, document it. A layout that works in a browser can collapse in one of those clients.

An email framework lets you write the email in code or markup, in your own repository, and compiles it to HTML built for every client at once: nested tables, inline styles, and conditional comments with VML for Outlook. Most frameworks also make the layout responsive, so columns stack on a small screen. MJML, for example, says it is "responsive by design on most-popular email clients, even Outlook". A framework gets you most of the way, but no tool guarantees every client, so send a test to Gmail, Outlook and Apple Mail before your first real send.

Frameworks by language

Start from what your app already uses: the component model your team writes every day, or the language your backend runs.

React

  • React Email: React components (JSX or TSX), with a Tailwind component. Maintained by Resend, an email sending service. GitHub
  • JSX Email: React components (JSX or TSX), React 19, with a Tailwind component. Maintained by Andrew Powell (individual). GitHub
  • @unitpost/email: React components, or the same markup passed as a plain string so it renders without a JSX build step. Styled with Tailwind-style className. Maintained by Unitpost, an email sending service. GitHub
  • mjml-react (@faire/mjml-react): React components named after MJML tags, compiled to MJML, then to HTML. Maintained by Faire. Maintenance-only. GitHub
  • Mailing: React components rendered through MJML. Maintained by the sofn-xyz GitHub organization. Maintenance-only. GitHub
  • mjml-react (Wix original): the package named mjml-react on npm. Abandoned. Install @faire/mjml-react instead. GitHub

Vue

  • Maizzle: Vue single-file components with Tailwind CSS, built through Vite. Maintained by the maizzle GitHub organization. GitHub
  • Vue Email: Vue 3 single-file components. Abandoned (last release 2024). GitHub

Svelte

  • better-svelte-email: Svelte 5 components, Tailwind v4 or plain CSS. Maintained by Anatole Dufour (individual). GitHub
  • svelte-email (original): Svelte 3 components. Abandoned (last release 2023). GitHub

MJML and other markup

  • MJML: MJML markup, an XML dialect, rendered in Node. Maintained by Mailjet, an email sending service. The ports in the sections below reimplement or wrap it. GitHub
  • Foundation for Emails: HTML with Inky custom tags (rows, columns), compiled to tables. Maintained by the foundation GitHub organization. Maintenance-only, succeeded by Inky v2 (see Rust). GitHub
  • HEML: HTML-like tags. Maintained by SparkPost, an email sending service. Abandoned (last release 2017). GitHub

Go

  • gomjml: MJML markup, native Go port. Maintained by Preslav Rachev (individual). It does not inline CSS itself. GitHub
  • mgml: MJML markup, native Go port. Maintained by Konstantin Rozhkov (individual). GitHub
  • mjml-go (Boostport): the JavaScript MJML, run as WebAssembly. Maintained by the Boostport GitHub organization. Maintenance-only. GitHub
  • Hermes (go-hermes fork): a Go struct plus an optional theme, for transactional layouts (greeting, intro, action, outro). Maintained by the go-hermes GitHub organization. Maintenance-only. GitHub

Rust

  • MRML: MJML markup, a Rust reimplementation, usable as a library, a CLI, WebAssembly and from Python. Maintained by jdrouet (individual). GitHub
  • Inky v2: HTML with Inky custom tags, the Rust rewrite of Foundation for Emails' templating language, shipped as a CLI, a WebAssembly module and a Rust crate. Maintained by the foundation GitHub organization. In beta. GitHub

Python

  • mjml-python (FelixSchwarz, PyPI mjml): MJML markup, pure Python. Maintained by Felix Schwarz (individual). GitHub
  • mjml-python (mgd020, PyPI mjml-python): MJML markup, a Python wrapper around MRML. Maintained by mgd020 (individual). GitHub
  • django-mjml: a {% mjml %} template tag in Django that calls Node.js mjml. Maintained by Igor Melnyk (individual). GitHub

Ruby

  • mjml-rails: MJML markup in Rails views, rendered by Node.js mjml or by MRML. Maintained by Simon Loffler (individual) and Steven Pickles. GitHub

Elixir

  • mjml (Hex): MJML markup through Rust NIF bindings to MRML. Maintained by Paul Goetze (individual). GitHub

Java

  • mjml4j: MJML markup, a pure Java 17 port, rendered in-process. Maintained by Sylvain Jermini (digitalfondue). Targets MJML 4. GitHub
  • mjml-java: MJML markup, pure Java with no dependencies, plus a Spring module. Maintained by Justin Putney (individual). GitHub
  • freefair MJML Gradle plugin: compiles .mjml files at build time with the MJML CLI, so it needs Node. Part of the freefair Gradle plugins. Maintenance-only. GitHub
  • kotlin-ehtml: a Kotlin DSL that writes table-based HTML with inlined CSS and Outlook conditionals. Maintained by one individual. Pre-release. GitHub

CSS inliners

Inliners sit next to the frameworks, and most frameworks call one. They take HTML plus a <style> block and move the declarations into style attributes. MJML, for example, inlines through juice.

  • juice (JavaScript): maintained by Automattic. GitHub
  • premailer (Ruby): maintained by the premailer GitHub organization. GitHub
  • css-inline (Rust core, bindings for Python, Ruby, JavaScript, Java, C, PHP and WebAssembly): maintained by an individual. GitHub
  • premailer (Python): maintained by Peter Bengtsson (individual). Abandoned (last release 2021). GitHub

Conclusion

Pick the framework that matches the language and the component model you already use: React Email or JSX Email for React, Maizzle for Vue, better-svelte-email for Svelte, and MJML or one of its ports everywhere else, including mjml4j in Java. MJML has the widest reach, with renderers in Node, Rust, Go, Python, Ruby, Elixir and Java, so a team that mixes languages can share one template format. Check the status note before you adopt a tool, and test the output in the inboxes your users read.

Ready to get started?

Send the HTML your framework renders

Free plan available. No credit card required.

Start for free

FAQ

Why do email frameworks output tables and inline CSS?

MJML describes its output as "responsive email HTML with nested tables and inline CSS", plus MSO conditional comments and VML for Outlook. Clients support different parts of HTML and CSS, and this is the markup the frameworks target. The framework writes it so you do not have to.

Do email frameworks make emails responsive?

Most do. MJML says its output is "responsive by design on most-popular email clients, even Outlook", Foundation for Emails describes "responsive HTML emails that work in any email client, even Outlook", and Hermes generates "clean, responsive HTML e-mails". These are project claims, so check the result on a phone before you rely on it.

Which email framework is still maintained?

As read on 2026-11-05, active: React Email, JSX Email, @unitpost/email, MJML, Maizzle, better-svelte-email, gomjml, mgml, MRML, both Python MJML ports, django-mjml, mjml-rails, the Elixir MJML package, mjml4j and mjml-java, plus Inky v2 in beta and the CSS inliners juice, Ruby premailer and css-inline. Maintenance-only: @faire/mjml-react, Mailing, Foundation for Emails, mjml-go, the freefair MJML Gradle plugin and Hermes. Abandoned: Vue Email, HEML, the original svelte-email, the Wix mjml-react and the Python premailer.

Do I need an account at a sending service to use one?

No. Each tool here turns your template into an HTML string, and you send that string through any provider. Four are maintained by a sending service: React Email by Resend, MJML by Mailjet, @unitpost/email by Unitpost and HEML by SparkPost.

Can I render MJML without Node?

Yes. MRML renders MJML in Rust, gomjml and mgml in Go, mjml-go in Go through WebAssembly, the Python and Elixir packages through MRML or pure Python, and mjml4j and mjml-java in pure Java. mjml-rails can use MRML or Node, and django-mjml calls Node.