MJML reaches another level with the release of v3 🎓

Nicolas Garnier
MJML: Making Responsive Email Easy
4 min readOct 18, 2016


8 months after its official release and 5 months after the release of MJML v2, today marks another great milestone for MJML: MJML v3 is out! Big up to our community and contributors who played a big part in this release: Alex, András, Arthur, Connor, Dale, Martin, Meriadec, Uelb and everyone else who helped us!

To install this new version, all you have to do is npm update mjml -g.

MJML v3 brings structural changes such as the validation of the markup and a CSS inliner, as well as incremental changes with the improvement of existing components. Let’s review those changes together.

The MJML engine can now detect syntax and structure errors in your code 🔮

This feature is an exciting addition to the engine that will enable you to solve issues before they even happen. Upon rendering, the engine will check for 2 types of errors:

  • Structure errors: a component is used inside another component while it’s forbidden or the component is not registered. Example: <mj-button> is used inside <mj-section> (it should only be used inside <mj-column>or <mj-hero-content>)
  • Attribute errors: an attribute is used on a component that does not support this attribute. Example: the attribute “src” is used on the component <mj-text>(<mj-text> doesn’t support the attribute “src”).

To validate MJML, three modes are available:

  • skip: your document is rendered without even going through validation
  • soft: your document is going through validation and is rendered, even if there are errors
  • strict: your document is going through validation and is not rendered if there is any error

Once validation is completed, all of the errors caught in the document are thrown with:

  • The line of the document where the error was found
  • The component on which the error was found (whether it is the wrong use of an attribute or if a component was used where it should not be)
  • The error itself: where this component should be used or which attribute was used where it should not be

Example:Line 12 (mj-button) — mj-button cannot be used inside mj-section, only inside: mj-column, mj-hero-content.

<mj-style> enables you to use CSS directly inside MJML documents 🎨

MJML supports its own set of styles through the use of attributes on components directly or in the head through <mj-attributes>. However, you might want to use CSS that will be applied to the HTML generated by MJML or even to the HTML you use inside your MJML document (inside <mj-text> for example). Be delighted, this is now possible with <mj-style>!

<mj-style> goes into the head of your MJML component and supports any CSS except media queries (at the moment), including CSS styles and classes. Note that CSS classes will apply when used on HTML but not on MJML components.

To ensure the styles work in every email clients, the CSS style you set in <mj-style> will automatically be inlined to the HTML generated.

More control over how your columns stack on mobile, again! 🎛

Sometimes, you want the order of the columns to be different between the mobile and desktop layouts. A picture (or two) is worth a thousand words, here is the demo:

Desktop and mobile views

Here, we have two different layouts on desktop: text first (aligned to the left), image second (aligned to the right) in the first section and then image first, text second in the second section. However, we don’t want the order to change between sections on mobile as we always want to have the image above the text.

To achieve this, all you have to do is use the direction attribute in the first section and set it to rtl. It will change the order in which columns display on desktop. Because MJML is mobile-first, structure the columns in the order you want them to stack on mobile, and use direction to change the order they display on desktop. You can check the code of this demo here.

The components you already love levelled up too 🆙

In addition to those new features, several components were improved:

  • mj-fontnow enables users to override default MJML fonts like Roboto
  • mj-social now supports inner-padding to add padding between social networks
  • mj-button now supports the border-left/right/bottom/top and width attributes
  • mj-section now supports the border-left/right/bottom/top attributes
  • mj-column now supports the border-left/right/bottom/top attributes

To see the full list of changes, including bug fixes, check the Github backlog.

What’s next? 🔍

This is just the beginning and we’ve got a lot in mind for next releases. Among our priorities, we want to add more features leveraging progressive enhancement, a more intensive use of media queries following the changes in Gmail and more interactive components.

If you missed the news, we made the roadmap public last month so make sure to check it out to always know what we’re up to and better yet, contribute to help us make MJML always better!

Interested in MJML? Join the team and the community on Slack, Twitter and always keep up to date by subscribing to the newsletter on https://mjml.io.



Nicolas Garnier
MJML: Making Responsive Email Easy

Building something new at Primary VC. Previously product at Treat, Gorgias, Mailgun, Mailjet, and proud daddy of open-source software MJML (15K stars)