MJML preview, lint, compile for Visual Studio Code.
221
stars
91
commits
TypeScript
primary language
Sep 11, 2026
updated
This is a fork of original @attilabuti VSC extension : https://github.com/attilabuti/vscode-mjml
MJML preview, lint, compile for Visual Studio Code.
Try it live support.

Press F1, type ext install vscode-mjml.
Start command palette (with Ctrl+Shift+P or F1) and start typing MJML.
The following command is available:
| Name | Default | Description |
|---|---|---|
mjml.autoClosePreview | true | Automatically close preview when all open MJML documents have been closed. |
mjml.allowIncludes | false | Enable mj-include processing. Disabled by default for security. |
mjml.autoPreview | false | Automatically update preview when switching between MJML documents. |
mjml.beautify | {} | Prettier options for beautifying MJML. (Priority: .prettierrc > mjml.beautify > defaults). See Prettier options. |
mjml.beautifyHtmlOutput | false | Beautify HTML output. (Works when mjml.minifyHtmlOutput aren't enabled.) |
mjml.exportType | .html | Specifies 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.keepComments | true | Keep custom comments in HTML output when exporting MJML files. |
mjml.lintEnable | true | Enable/disable MJML linter (requires restart). |
mjml.lintWhenTyping | true | Whether the linter is run on type or on save. |
mjml.mailer | mailjet | Send 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.minifyHtmlOutput | true | Minify 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.preserveFocus | true | Preserve focus of Text Editor after preview open. |
mjml.previewBackgroundColor | #FFFFFF | Preview background color. |
mjml.showSaveDialog | false | Show the save as dialog instead of input box. |
mjml.switchOnSeparateFileChange | true | Automatically switch previews when editing a different file. |
mjml.templateGallery | false | Show the template gallery instead of quick pick. |
mjml.templateGalleryAutoClose | true | Automatically close template gallery when selecting a template. |
mjml.updateWhenTyping | true | Update preview when typing. |
mjml.allowIncludes and mjml.includePath)MJML 5 disables include processing by default for security.
mjml.allowIncludes to true to enable <mj-include> processing.mjml.allowIncludes as false (default) to ignore all includes.mjml.includePath to allow includes outside the current template base path.When includes are enabled:
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:
"[\"resources/templates\"]").Scope note:
mjml.allowIncludes and mjml.includePath.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.
| Trigger | URL | Content |
|---|---|---|
mjall <mj-all | mj-all | <mj-all /> |
mjattributes <mj-attributes | mj-attributes | <mj-attributes></mj-attributes> |
mjhtmlattributes <mj-html-attributes | mj-html-attributes | <mj-html-attributes></mj-html-attributes> |
mjbody <mj-body | mj-body | <mj-body></mj-body> |
mjbreakpoint <mj-breakpoint | mj-breakpoint | <mj-breakpoint width="" /> |
mjbutton <mj-button | mj-button | <mj-button></mj-button> |
mjcarousel <mj-carousel | mj-carousel | <mj-carousel></mj-carousel> |
mjcarousel-image <mj-carousel-image | mj-carousel-image | <mj-carousel-image src="" /> |
mjclass <mj-class | mj-class | <mj-class name="" /> |
mjcolumn <mj-column | mj-column | <mj-column width=""></mj-column> |
mjdivider <mj-divider | mj-divider | <mj-divider /> |
mjfont <mj-font | mj-font | <mj-font name="" href="" /> |
mjgroup <mj-group | mj-group | <mj-group></mj-group> |
mjhead <mj-head | mj-head | <mj-head></mj-head> |
mjhero <mj-hero | mj-hero | <mj-hero></mj-hero> |
mjimage <mj-image | mj-image | <mj-image src="" alt="" /> |
mjinclude <mj-include | mj-include | <mj-include path="" /> |
mjraw <mj-raw | mj-raw | <mj-raw></mj-raw> |
mjsection <mj-section | mj-section | <mj-section></mj-section> |
mjsocial <mj-social | mj-social | <mj-social></mj-social> |
mjsocialelement <mj-social-element | mj-social-element | <mj-social-element></mj-social-element> |
mjstyle <mj-style | mj-style | <mj-style></mj-style> |
mjtable <mj-table | mj-table | <mj-table></mj-table> |
mjtext <mj-text | mj-text | <mj-text></mj-text> |
mjtitle <mj-title | mj-title | <mj-title></mj-title> |
mjml <mjml | mjml | <mjml></mjml> |
mjpreview <mj-preview | mj-preview | <mj-preview></mj-preview> |
mjspacer <mj-spacer | mj-spacer | <mj-spacer height="" /> |
mjwrapper <mj-wrapper | mj-wrapper | <mj-wrapper></mj-wrapper> |
mjaccordion <mj-accordion | mj-accordion | <mj-accordion></mj-accordion> |
mjaccordion-element <mj-accordion-element | mj-accordion-element | <mj-accordion-element>...</mj-accordion-element> |
mjnavbar <mj-navbar | mj-navbar | <mj-navbar></mj-navbar> |
mjnavbarlink <mj-navbar-link | mj-navbar-link | <mj-navbar-link></mj-navbar-link> |
mjml- | Basic MJML Template |
Please see the Nodemailer documentation for more information.
"mjml.nodemailer": {
"service": "Gmail",
"auth": {
"user": "youremail@gmail.com",
"pass": "password"
}
}
"mjml.nodemailer": {
"host": "smtp.mailtrap.io",
"port": 2525,
"auth": {
"user": "username",
"pass": "password"
}
}
"mjml.nodemailer": {
"host": "smtp.ethereal.email",
"port": 587,
"auth": {
"user": "youremail@ethereal.email",
"pass": "password"
}
}
https://github.com/mjmlio/vscode-mjml/blob/master/CHANGELOG.md
Submit the issues if you find any bug or have any suggestion.
Fork the repo and submit pull requests.
Main Author: Attila Buti (@attilabuti)
A big thanks to the people that have contributed to this project:
This extension is licensed under the [MIT License][license-url].
TypeScript
96.9%
HTML
2.2%
MJML preview, lint, compile for Visual Studio Code.
221
stars
91
commits
TypeScript
primary language
Sep 11, 2026
updated
This is a fork of original @attilabuti VSC extension : https://github.com/attilabuti/vscode-mjml
MJML preview, lint, compile for Visual Studio Code.
Try it live support.

Press F1, type ext install vscode-mjml.
Start command palette (with Ctrl+Shift+P or F1) and start typing MJML.
The following command is available:
| Name | Default | Description |
|---|---|---|
mjml.autoClosePreview | true | Automatically close preview when all open MJML documents have been closed. |
mjml.allowIncludes | false | Enable mj-include processing. Disabled by default for security. |
mjml.autoPreview | false | Automatically update preview when switching between MJML documents. |
mjml.beautify | {} | Prettier options for beautifying MJML. (Priority: .prettierrc > mjml.beautify > defaults). See Prettier options. |
mjml.beautifyHtmlOutput | false | Beautify HTML output. (Works when mjml.minifyHtmlOutput aren't enabled.) |
mjml.exportType | .html | Specifies 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.keepComments | true | Keep custom comments in HTML output when exporting MJML files. |
mjml.lintEnable | true | Enable/disable MJML linter (requires restart). |
mjml.lintWhenTyping | true | Whether the linter is run on type or on save. |
mjml.mailer | mailjet | Send 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.minifyHtmlOutput | true | Minify 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.preserveFocus | true | Preserve focus of Text Editor after preview open. |
mjml.previewBackgroundColor | #FFFFFF | Preview background color. |
mjml.showSaveDialog | false | Show the save as dialog instead of input box. |
mjml.switchOnSeparateFileChange | true | Automatically switch previews when editing a different file. |
mjml.templateGallery | false | Show the template gallery instead of quick pick. |
mjml.templateGalleryAutoClose | true | Automatically close template gallery when selecting a template. |
mjml.updateWhenTyping | true | Update preview when typing. |
mjml.allowIncludes and mjml.includePath)MJML 5 disables include processing by default for security.
mjml.allowIncludes to true to enable <mj-include> processing.mjml.allowIncludes as false (default) to ignore all includes.mjml.includePath to allow includes outside the current template base path.When includes are enabled:
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:
"[\"resources/templates\"]").Scope note:
mjml.allowIncludes and mjml.includePath.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.
| Trigger | URL | Content |
|---|---|---|
mjall <mj-all | mj-all | <mj-all /> |
mjattributes <mj-attributes | mj-attributes | <mj-attributes></mj-attributes> |
mjhtmlattributes <mj-html-attributes | mj-html-attributes | <mj-html-attributes></mj-html-attributes> |
mjbody <mj-body | mj-body | <mj-body></mj-body> |
mjbreakpoint <mj-breakpoint | mj-breakpoint | <mj-breakpoint width="" /> |
mjbutton <mj-button | mj-button | <mj-button></mj-button> |
mjcarousel <mj-carousel | mj-carousel | <mj-carousel></mj-carousel> |
mjcarousel-image <mj-carousel-image | mj-carousel-image | <mj-carousel-image src="" /> |
mjclass <mj-class | mj-class | <mj-class name="" /> |
mjcolumn <mj-column | mj-column | <mj-column width=""></mj-column> |
mjdivider <mj-divider | mj-divider | <mj-divider /> |
mjfont <mj-font | mj-font | <mj-font name="" href="" /> |
mjgroup <mj-group | mj-group | <mj-group></mj-group> |
mjhead <mj-head | mj-head | <mj-head></mj-head> |
mjhero <mj-hero | mj-hero | <mj-hero></mj-hero> |
mjimage <mj-image | mj-image | <mj-image src="" alt="" /> |
mjinclude <mj-include | mj-include | <mj-include path="" /> |
mjraw <mj-raw | mj-raw | <mj-raw></mj-raw> |
mjsection <mj-section | mj-section | <mj-section></mj-section> |
mjsocial <mj-social | mj-social | <mj-social></mj-social> |
mjsocialelement <mj-social-element | mj-social-element | <mj-social-element></mj-social-element> |
mjstyle <mj-style | mj-style | <mj-style></mj-style> |
mjtable <mj-table | mj-table | <mj-table></mj-table> |
mjtext <mj-text | mj-text | <mj-text></mj-text> |
mjtitle <mj-title | mj-title | <mj-title></mj-title> |
mjml <mjml | mjml | <mjml></mjml> |
mjpreview <mj-preview | mj-preview | <mj-preview></mj-preview> |
mjspacer <mj-spacer | mj-spacer | <mj-spacer height="" /> |
mjwrapper <mj-wrapper | mj-wrapper | <mj-wrapper></mj-wrapper> |
mjaccordion <mj-accordion | mj-accordion | <mj-accordion></mj-accordion> |
mjaccordion-element <mj-accordion-element | mj-accordion-element | <mj-accordion-element>...</mj-accordion-element> |
mjnavbar <mj-navbar | mj-navbar | <mj-navbar></mj-navbar> |
mjnavbarlink <mj-navbar-link | mj-navbar-link | <mj-navbar-link></mj-navbar-link> |
mjml- | Basic MJML Template |
Please see the Nodemailer documentation for more information.
"mjml.nodemailer": {
"service": "Gmail",
"auth": {
"user": "youremail@gmail.com",
"pass": "password"
}
}
"mjml.nodemailer": {
"host": "smtp.mailtrap.io",
"port": 2525,
"auth": {
"user": "username",
"pass": "password"
}
}
"mjml.nodemailer": {
"host": "smtp.ethereal.email",
"port": 587,
"auth": {
"user": "youremail@ethereal.email",
"pass": "password"
}
}
https://github.com/mjmlio/vscode-mjml/blob/master/CHANGELOG.md
Submit the issues if you find any bug or have any suggestion.
Fork the repo and submit pull requests.
Main Author: Attila Buti (@attilabuti)
A big thanks to the people that have contributed to this project:
This extension is licensed under the [MIT License][license-url].
TypeScript
96.9%
HTML
2.2%