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.
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.html
MJML 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 15 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.
Test your MJML email across 15 clients
Paste your MJML source and get a compatibility report with framework-specific fix snippets.
Preview your emailFree plan — 30 previews/day