Using MJML in Elixir & Phoenix

How to create responsive HTML emails for your Phoenix app with ease

Paul Götze
The Startup
Published in
5 min readAug 2, 2020


If you ever tried to create responsive emails, you may have heard of MJML — the Mailjet Markup Language — supposedly “The only framework that makes responsive email easy”.

MJML provides a collection of reusable and extensible components, that allow you to build HTML email designs which are responsive by default and look great on all kinds of devices and email clients. MJML comes as an npm package, and provides a CLI or can be run directly from JavaScript code.

I’ve used MJML email templates with Ruby on Rails and was wondering if there’s something similar to the mjml-rails gem that I could use in an Elixir Phoenix app.

And indeed, there’s a hex package that provides a Phoenix Template Engine for MJML. However, the engine’s rendering flow is inverted. So I wasn’t able to create dynamic emails, because my EEx templates were not parsed until after the MJML transpiling. This means that all embedded Elixir is detected as invalid elements in the MJML components and the template creation fails altogether.

After fiddling around for a while with Phoenix Template Engines without success, I found another way to create dynamic MJML email templates in my app.

Here’s the setup that worked for me using Bamboo for sending emails:

  • add the mjmldependency to the project (npm, or hex NIF package)
  • render email templates (EEx) as usual
  • use the rendered email template as input for an additional MJML transpiling step
  • replace the HTML body content of the EEx rendering result with the transpiled MJML template

In a first step I tried using the mjml npm package, which left me with some performance questions. In a subsequent step I wrote the mjml Hex package that wraps an MJML Rust implementation as NIFs (Native Implemented Functions). Let’s look into the steps from above in detail and implement a working example — starting with the npm setup.

Adding MJML Support via the npm Package

First we add the mjml npm package to our Phoenix app’s package.json by running…



Paul Götze
The Startup

Authoring code. Drawing stuff. Comics addict and fan of bad jokes. Creator of &