MJML

May 7, 2026 ยท View on GitHub

This is a fork of original @attilabuti VSC extension : https://github.com/attilabuti/vscode-mjml

MJML preview, lint, compile for Visual Studio Code.

Features

  • Live preview for MJML files. Preview updates as you type.
  • Inline errors (squiggle underlines). Linter based on atom-linter-mjml.
  • Export HTML file from MJML.
  • Copy the result HTML to clipboard.
  • Send email with Nodemailer or Mailjet.
  • Code snippets for MJML. Based on mjml-syntax.
  • Fetch official templates. Based on email-templates.
  • Beautify MJML code.
  • MJML syntax highlight. Based on mjml-syntax.
  • Built-in MJML documentation with Try it live support.

It looks like this

MJML Preview

MJML Lint

Installation

Press F1, type ext install vscode-mjml.

Usage

Start command palette (with Ctrl+Shift+P or F1) and start typing MJML.

Available commands

The following command is available:

  • MJML: Beautify or Format Document Beautify MJML code.
  • MJML: Copy HTML Copy the result HTML to clipboard.
  • MJML: Export HTML Export HTML file from MJML.
  • MJML: Open Preview to the Side Opens a preview in a column alongside the current document.
  • MJML: Send Email Send email with Nodemailer or Mailjet.
  • MJML: Template Fetch official templates.
  • MJML: Documentation open the MJML documentation.
  • MJML: Search in MJML documentation search for the selected mj-element in the MJML documentation.
  • MJML: Version Shows the version of MJML.

Settings

NameDefaultDescription
mjml.autoClosePreviewtrueAutomatically close preview when all open MJML documents have been closed.
mjml.allowIncludesfalseEnable mj-include processing. Disabled by default for security.
mjml.autoPreviewfalseAutomatically update preview when switching between MJML documents.
mjml.beautify{}Prettier options for beautifying MJML. (Priority: .prettierrc > mjml.beautify > defaults). See Prettier options.
mjml.beautifyHtmlOutputfalseBeautify HTML output. (Works when mjml.minifyHtmlOutput aren't enabled.)
mjml.exportType.htmlSpecifies the file type of the output file.
mjml.includePath[]Additional directories to allow for <mj-include> lookups when mjml.allowIncludes is enabled. Supports absolute paths, or paths relative to the workspace root.
mjml.keepCommentstrueKeep custom comments in HTML output when exporting MJML files.
mjml.lintEnabletrueEnable/disable MJML linter (requires restart).
mjml.lintWhenTypingtrueWhether the linter is run on type or on save.
mjml.mailermailjetSend email with Nodemailer or Mailjet. Possible values are 'nodemailer' and 'mailjet'. See examples of Nodemailer config
mjml.mailFromName Sender name.
mjml.mailjetAPIKey Mailjet API Key.
mjml.mailjetAPISecret Mailjet API Secret.
mjml.mailRecipients Comma separated list of recipients email addresses.
mjml.mailSender Sender email address. (Mailjet: must be a verified sender.)
mjml.mailSubject Email subject.
mjml.minifyHtmlOutputtrueMinify HTML output.
mjml.mjmlConfigPath The path or directory of the .mjmlconfig (or .mjmlconfig.js) file (for custom components use)
mjml.nodemailer{}Nodemailer configuration. Please see the Nodemailer documentation for more information.
mjml.preserveFocustruePreserve focus of Text Editor after preview open.
mjml.previewBackgroundColor#FFFFFFPreview background color.
mjml.showSaveDialogfalseShow the save as dialog instead of input box.
mjml.switchOnSeparateFileChangetrueAutomatically switch previews when editing a different file.
mjml.templateGalleryfalseShow the template gallery instead of quick pick.
mjml.templateGalleryAutoClosetrueAutomatically close template gallery when selecting a template.
mjml.updateWhenTypingtrueUpdate preview when typing.

Include security settings (mjml.allowIncludes and mjml.includePath)

MJML 5 disables include processing by default for security.

  • Set mjml.allowIncludes to true to enable <mj-include> processing.
  • Keep mjml.allowIncludes as false (default) to ignore all includes.
  • Use mjml.includePath to allow includes outside the current template base path.

When includes are enabled:

  • Includes in the same folder (or subfolders) as the current MJML file are allowed.
  • Includes outside that folder are denied unless the target folder is listed in mjml.includePath.

mjml.includePath accepts absolute paths or workspace-relative paths.

Correct JSON example:

{
    "mjml.allowIncludes": true,
    "mjml.includePath": ["resources/templates", "shared/partials"]
}

Settings UI note:

  • In the Settings UI, add each include path as a separate array item.
  • Do not paste a full JSON array as one item (for example "[\"resources/templates\"]").

Scope note:

  • Workspace settings override User settings.
  • If include behavior is unexpected, check both User and Workspace values for mjml.allowIncludes and mjml.includePath.

Snippets

Each snippet can be triggered by its keyword (e.g. mjbody) or by typing the opening tag directly (e.g. <mj-body). Both trigger the same completion.

TriggerURLContent
mjall <mj-allmj-all<mj-all />
mjattributes <mj-attributesmj-attributes<mj-attributes></mj-attributes>
mjhtmlattributes <mj-html-attributesmj-html-attributes<mj-html-attributes></mj-html-attributes>
mjbody <mj-bodymj-body<mj-body></mj-body>
mjbreakpoint <mj-breakpointmj-breakpoint<mj-breakpoint width="" />
mjbutton <mj-buttonmj-button<mj-button></mj-button>
mjcarousel <mj-carouselmj-carousel<mj-carousel></mj-carousel>
mjcarousel-image <mj-carousel-imagemj-carousel-image<mj-carousel-image src="" />
mjclass <mj-classmj-class<mj-class name="" />
mjcolumn <mj-columnmj-column<mj-column width=""></mj-column>
mjdivider <mj-dividermj-divider<mj-divider />
mjfont <mj-fontmj-font<mj-font name="" href="" />
mjgroup <mj-groupmj-group<mj-group></mj-group>
mjhead <mj-headmj-head<mj-head></mj-head>
mjhero <mj-heromj-hero<mj-hero></mj-hero>
mjimage <mj-imagemj-image<mj-image src="" alt="" />
mjinclude <mj-includemj-include<mj-include path="" />
mjraw <mj-rawmj-raw<mj-raw></mj-raw>
mjsection <mj-sectionmj-section<mj-section></mj-section>
mjsocial <mj-socialmj-social<mj-social></mj-social>
mjsocialelement <mj-social-elementmj-social-element<mj-social-element></mj-social-element>
mjstyle <mj-stylemj-style<mj-style></mj-style>
mjtable <mj-tablemj-table<mj-table></mj-table>
mjtext <mj-textmj-text<mj-text></mj-text>
mjtitle <mj-titlemj-title<mj-title></mj-title>
mjml <mjmlmjml<mjml></mjml>
mjpreview <mj-previewmj-preview<mj-preview></mj-preview>
mjspacer <mj-spacermj-spacer<mj-spacer height="" />
mjwrapper <mj-wrappermj-wrapper<mj-wrapper></mj-wrapper>
mjaccordion <mj-accordionmj-accordion<mj-accordion></mj-accordion>
mjaccordion-element <mj-accordion-elementmj-accordion-element<mj-accordion-element>...</mj-accordion-element>
mjnavbar <mj-navbarmj-navbar<mj-navbar></mj-navbar>
mjnavbarlink <mj-navbar-linkmj-navbar-link<mj-navbar-link></mj-navbar-link>
mjml-Basic MJML Template

Nodemailer configuration

Please see the Nodemailer documentation for more information.

Gmail

"mjml.nodemailer": {
    "service": "Gmail",
    "auth": {
        "user": "youremail@gmail.com",
        "pass": "password"
    }
}

Mailtrap

"mjml.nodemailer": {
    "host": "smtp.mailtrap.io",
    "port": 2525,
    "auth": {
        "user": "username",
        "pass": "password"
    }
}

Ethereal

"mjml.nodemailer": {
    "host": "smtp.ethereal.email",
    "port": 587,
    "auth": {
        "user": "youremail@ethereal.email",
        "pass": "password"
    }
}

Change Log

https://github.com/mjmlio/vscode-mjml/blob/master/CHANGELOG.md

Issues

Submit the issues if you find any bug or have any suggestion.

Contribution

Fork the repo and submit pull requests.

Contributors

Main Author: Attila Buti (@attilabuti)

A big thanks to the people that have contributed to this project:

License

This extension is licensed under the [MIT License][license-url].