“Hey. We’re entirely rebuilding MJML from scratch”. Announcing MJML v4 🔥

After a little more than a year, an increasing number of downloads (20,000 in February!) and an always more active community, we decided that it was time to take a fresh start.

First, don’t freak out. Templates created with MJML v3.x will be fully compatible with MJML v4, you’ll still be able to render MJML emails like you are today, and we won’t break the look and feel of your emails from a version to another.

What will change is mostly the internals of MJML, especially as we won’t use React anymore. Now you’re wondering… “Why would you do that?!”. Here’s a few reasons why.

Less overhead for better performances 🦄

React is a really powerful library, we love it and still use it in a lot of our other projects. The Facebook library enabled us to prototype and build MJML very fast, and we’re thankful for that.

However, React was also initially built for another purpose and is not the best for our needs. While adding a few hundred milliseconds load time is totally ok for website and interfaces, it can quickly add up when rendering a lot of and/or long MJML emails.

From our early tests (MJML 4 is a work in progress), by rewriting MJML in plain JavaScript, we’re making the rendering of MJML emails up to 35 times faster. This is a really huge change, especially when you integrate MJML in your app. This change will also improve the performances of the MJML API which are directly tied to MJML’s ability to scale.

Performances benchmark comparing operations per seconds between MJML v3 and MJML v4

Less magic for a better experience creating components 🎩

A great thing with React was the ability to leverage its components approach, as MJML is component-based too. However, we also quickly ran into limitations due to React.

Don’t forget, we’re doing HTML email

And HTML email is pretty twisted. Among a few things, we had to use postRender methods to add conditional comments for Outlook or deal with non-standard HTML attributes that React wouldn’t like. This also meant that MJML components weren’t just React components, which could be confusing.

Example: using a postRender on mj-divider to add conditional comments for Outlook

Requiring to know React to create components wasn’t the most inclusive

As much as we love React, it added an obscure veil to anyone not familiar with it when it comes to creating components. Switching to plain JavaScript, which is much more widely known, makes it more straightforward to understand how components work.

A good opportunity to solve deep issues at the core of MJML 🔧

We’re taking advantage of this breaking (internal) change to concentrate on structural issues that were introduced since the origins of MJML.

Introducing a parser better suited to our needs

We’re having a few issues with the parser we use at the moment, cheerio. While it is a great library, using htmlparser2 (on which cheerio is based) directly enable us to have more control over the way we parse MJML.

Adding more configuration to MJML

To make MJML always more configurable and cleaner, we’re doing a few organisational changes. For example, we’ll state the relation dependencies such as parent and children tags between components in a separate configuration files, instead of stating it in the components itself. This will enable us to remove any dependency between components.

Example: in MJML v3, section is dependent on container and wrapper because of the relation dependency

Building MJML together

As always, we’re really serious about hearing and integrating your feedback. If you feel like we should do something different in this new version of MJML, please open an issue and make your voice heard! You can also follow and contribute to the development of MJML 4 on the branch next on Github.

Feel free to share feedback in comments, on Twitter and directly on Slack! Want to be the first to know about what’s new in MJML? Subscribe to the newsletter from the website.