MJML Tutorial: Build Responsive Emails Without Fighting CSS
MJML is a markup language that compiles to responsive HTML email. You write semantic components, and MJML handles the table layouts, inline CSS, and client-specific hacks.
MJML eliminates the pain of writing raw nested tables and Outlook conditional comments. By declaring layouts with semantic tags like <mj-section> and <mj-column>, the MJML compiler automatically produces cross-client compatible HTML with inline styles, ghost tables for Windows Outlook, and fluid mobile breakpoints.
What MJML does
MJML abstracts away the complexity of HTML email. When you write <mj-section> and <mj-column>, MJML compiles these to nested <table> elements with precise width calculations, media queries for responsiveness, and inlined styles for maximum CSS compatibility.
The result is HTML that works in Outlook, Gmail, Apple Mail, and every other major client, without you having to write any of the underlying table markup.
Installation
npm install mjml
# Compile an MJML file to HTML
npx mjml input.mjml -o output.html
# Watch mode for development
npx mjml --watch input.mjml -o output.htmlMJML v5 is now async: the compileMjml() function returns a Promise. If you're upgrading from v4, update your build scripts to await the result.
Core components
mj-bodyRoot container. Sets background color and width for the entire email.
mj-sectionHorizontal row. Compiles to a <table> with one <tr>. Accepts background-color, padding, and full-width.
mj-columnVertical column within a section. Automatically calculates percentage widths based on sibling count.
mj-textText block with full inline CSS support. Wraps content in a <td> with proper padding.
mj-imageResponsive image with automatic width calculation and alt text support.
mj-buttonCTA button rendered as a <table>-based structure for universal client support.
mj-dividerHorizontal line. More reliable than <hr> across email clients.
mj-spacerEmpty vertical space. Use instead of margin for consistent spacing.
A complete example
<mjml>
<mj-head>
<mj-attributes>
<mj-all font-family="Arial, sans-serif" />
<mj-text font-size="14px" color="#333333" line-height="1.6" />
</mj-attributes>
</mj-head>
<mj-body background-color="#f6f6f6">
<mj-section background-color="#ffffff" padding="40px 30px">
<mj-column>
<mj-image
src="https://example.com/logo.png"
width="120px"
alt="Company Logo"
/>
<mj-text font-size="24px" font-weight="bold" padding-top="24px">
Welcome to our platform
</mj-text>
<mj-text>
We're glad you're here. Here's what you can do next:
</mj-text>
<mj-button
background-color="#000000"
color="#ffffff"
href="https://example.com/dashboard"
border-radius="6px"
font-size="14px"
>
Go to Dashboard
</mj-button>
</mj-column>
</mj-section>
<mj-section padding="20px 30px">
<mj-column>
<mj-text font-size="12px" color="#999999" align="center">
You received this because you signed up at example.com
</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>Multi-column layouts
MJML's column system handles responsive stacking automatically. On desktop, columns sit side by side. On mobile, they stack vertically. You don't need media queries:
<!-- Two-column layout , MJML handles the table math -->
<mj-section>
<mj-column>
<mj-image src="https://example.com/feature-1.png" alt="Feature 1" />
<mj-text font-weight="bold">Fast Setup</mj-text>
<mj-text>Get started in under 5 minutes.</mj-text>
</mj-column>
<mj-column>
<mj-image src="https://example.com/feature-2.png" alt="Feature 2" />
<mj-text font-weight="bold">Full Testing</mj-text>
<mj-text>Test across 21 email clients.</mj-text>
</mj-column>
</mj-section>
<!-- Three-column layout , each column is automatically 33.33% -->
<mj-section>
<mj-column>
<mj-text align="center">Plan A</mj-text>
</mj-column>
<mj-column>
<mj-text align="center">Plan B</mj-text>
</mj-column>
<mj-column>
<mj-text align="center">Plan C</mj-text>
</mj-column>
</mj-section>MJML vs React Email
Both compile to email-safe HTML, but they suit different workflows:
| Aspect | MJML | React Email |
|---|---|---|
| Syntax | Custom XML-like markup | JSX (React components) |
| Logic | Template literals or external templating | Full JavaScript/TypeScript |
| Responsive | Built-in (auto stacking) | Manual (you handle it) |
| Best for | Marketing emails, designers | Transactional emails, React teams |
Both are supported by Emailens. You can compare alternatives or paste either format directly into the preview tool.
Testing MJML emails
MJML's output is optimized for compatibility, but no tool can guarantee 100% consistency across clients. Outlook's Word rendering engine, Gmail's CSS stripping, and Apple Mail's dark mode all introduce edge cases.
Emailens accepts MJML source directly. It compiles, transforms per-client, and generates a compatibility report with MJML-specific fix suggestions.
See also: Compare MJML directly with React Email development, or read our deep dive on modern responsive email techniques.
Frequently Asked Questions
How does MJML handle responsive design across email clients?
MJML abstracts table-based responsive layouts behind intuitive tags like <mj-section> and <mj-column>. When compiled, it generates complex conditional MSO tables for Outlook and responsive media queries for modern mobile clients.
Do I need to manually inline CSS when using MJML?
No. The MJML engine automatically inlines styles declared inside <mj-attributes> and <mj-style inline='inline'> directly onto elements during compilation, ensuring Gmail and mobile clients receive inline CSS.
Can I include custom HTML or Outlook VML inside MJML?
Yes. The <mj-raw> tag allows you to inject arbitrary raw HTML, conditional comments (like <!--[if mso]>), or template syntax (Handlebars, Liquid, Jinja) directly into the generated output without MJML escaping it.
What is the difference between MJML and React Email?
MJML is a domain-specific XML markup language with built-in layout calculations that works across any backend language. React Email uses JSX and TypeScript within Node/React ecosystems, giving developers component composition and code sharing with web apps.
Test your MJML email across 21 clients
Paste your MJML source and get a compatibility report with framework-specific fix snippets.
Preview your emailFree plan, 30 previews/day
- •MJML: MJML Official Documentation & Component Architecture
- •Can I Email: Can I Email: HTML Email Support Tables
- •Mailjet: Mailjet: Why MJML is the Industry Standard for Responsive Email
- •Litmus: Litmus: Modern Email Development Frameworks Compared
Reviewed by Philippe KAM · Last updated: Mar 4, 2026
Building next-generation email preview and QA infrastructure for developers. Focused on reverse-engineering rendering engines across Outlook (Word MSO & New Outlook), Gmail, and Apple Mail to eliminate email rendering bugs before dispatch.