Published on

MJML4-Lambda: Convert MJML to HTML


Before we start, the folks at MailJet have a beta program for an API that essentially does the same thing as this lambda function.

With the latest version of MJML, there came a lot of nice features and upgrades. However, prior to version 4, the NPM module didn't include system API calls like fs, which can't be used in a web browser. This poses problems if you're integrating an MJML editor into your application and are not using Node.js as your backend. This is where an API or Lambda could provide a solution.

Our function's goal is to mirror the documented usage of MJML inside Node.js; so we need to accept the MJML and its options.

Example Post

    "body": {
        "mjml": "<mj-text>hello</mj-text>",
        "options": {
            "validationLevel": "strict"

The Lambda

const mjml2html   = require('mjml');
const isString = function(val) {
    return typeof val === 'string' || ((!!val && typeof val === 'object') && === '[object String]');

exports.handler = async (event, context, callback) => {

    // Log the event details so that they're viewable in the CloudWatch Logs

    // console.log('DATA:', event.body);
    const data = isString(event.body) ? JSON.parse(event.body) : event.body;
    const htmlOutput = mjml2html(data.mjml, data.options);

    // onError
        let errorList = JSON.stringify(htmlOutput.errors);
        return callback( errorList, sendRes(500, htmlOutput.html) );

    // success 
    return callback(null, sendRes(htmlOutput.errors.length ? 500 : 200, htmlOutput.html) );

const sendRes = (status, body) => {
  var response = {
    statusCode: status,
    headers: {
    body: body
  return response;


The code for this lambda is also available on GitHub. Please check there for the latest version just incase this post doesn't get updated.

Hope this helps! Hit me up on Twitter: @Mineo27 if you have any issues/questions.

Source Code Available

Want to check out the code repo for this post?

© 2015-2022