Letterbench › MJML templates
MJML email templates for SaaS
17 transactional and lifecycle emails in MJML 4 with Handlebars variables, compiled to Outlook-conditional HTML, with plain text and dark mode. Edit one theme file, rebuild, rerun the tests.
Get all 17 from £29 3 free (MIT)
Example: password reset MJML (free in Lite)
<mjml lang="en" dir="ltr">
<mj-head>
<mj-title>Reset your {{product_name}} password</mj-title>
<mj-preview>A password reset was requested for your account.</mj-preview>
<mj-attributes><mj-all font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif" /><mj-text color="#1A2230" padding="8px 32px" /><mj-section padding="0" /></mj-attributes>
<mj-style>
a { color: #2F5BEA; }
body { background: #F3F4F8; }
@media (prefers-color-scheme: dark) {
body, .lb-body, .lb-body > div { background: #0F1217 !important; }
.lb-card, .lb-card > table, .lb-card td { background: #171B22 !important; border-color: #2A313B !important; }
.lb-text div, .lb-text, .lb-code div, .lb-table td, .lb-table th, .lb-text h1 { color: #E8EBF0 !important; }
.lb-muted div, .lb-muted { color: #A9B3C0 !important; }
.lb-text a, .lb-muted a, .lb-rating a, .lb-eyebrow div { color: #8AB4FF !important; }
.lb-soft { background: #1E2533 !important; }
.lb-bd, .lb-bd p { border-color: #2A313B !important; }
}
[data-ogsc] .lb-text div, [data-ogsc] .lb-table td, [data-ogsc] .lb-text h1 { color: #E8EBF0 !important; }
[data-ogsb] .lb-card td { background: #171B22 !important; }
[data-ogsb] .lb-soft { background: #1E2533 !important; }
</mj-style>
</mj-head>
<mj-body background-color="#F3F4F8" width="600px" css-class="lb-body">
<mj-section padding="28px 0 14px"><mj-column>
<mj-image src="{{logo_url}}" alt="{{product_name}}" width="120px" align="left" padding="0 24px" />
</mj-column></mj-section>
<mj-wrapper padding="0 12px"><mj-section background-color="#FFFFFF" border-radius="12px" padding="28px 0 24px" css-class="lb-card" border="1px solid #E3E7EE" border-top="4px solid #2F5BEA"><mj-column>
<mj-text css-class="lb-eyebrow" font-size="12px" line-height="16px" font-weight="700" letter-spacing="1px" color="#2F5BEA" padding="0 32px 10px">SECURITY</mj-text>
<mj-text css-class="lb-text" font-size="26px" line-height="34px" font-weight="700" padding="0 32px 10px"><h1 style="margin:0;font-size:26px;line-height:34px;font-weight:700;letter-spacing:-0.3px;">Reset your password</h1></mj-text>
<mj-text css-class="lb-text" font-size="16px" line-height="26px">Hi {{user_first_name}}, we received a request to reset the password for your account.</mj-text>
<mj-button href="{{action_url}}" background-color="#2F5BEA" color="#FFFFFF" font-size="16px" font-weight="600" border-radius="8px" inner-padding="14px 28px" align="left" padding="18px 32px 10px">Choose a new password</mj-button>
<mj-text css-class="lb-muted" font-size="13px" line-height="20px" color="#525F70">If the button doesn't work, copy and paste this link into your browser:<br><a href="{{action_url}}" style="color:#2F5BEA;word-break:break-all;">{{action_url}}</a></mj-text>
<mj-text css-class="lb-muted" font-size="13px" line-height="20px" color="#525F70" padding-top="18px">This link expires in {{expiry_minutes}} minutes and can be used once. If you didn't ask for this, your password has not changed and you can ignore this email.</mj-text>
</mj-column></mj-section></mj-wrapper>
<mj-section padding="18px 12px 36px"><mj-column>
<mj-text css-class="lb-muted" font-size="12px" line-height="18px" color="#525F70" align="center">{{product_name}} · {{company_address}}<br>Need help? <a href="mailto:{{support_email}}" style="color:#525F70;">{{support_email}}</a></mj-text>
</mj-column></mj-section>
</mj-body></mjml>Same templates in React Email
Every template also ships as a typed React Email component.
FAQ
Which MJML version?
MJML 4. node build.js compiles every template to HTML and writes the plain text alongside it.
Do they work with SendGrid, Postmark or SES templates?
Yes. Variables are Handlebars ({{product_name}}), which SendGrid dynamic templates, Postmark and Amazon SES render. Examples are included.
Is the HTML Outlook-safe?
It is MJML's output with Outlook (MSO) conditional code, which the tests check for. We haven't tested in Outlook desktop itself, so test in your own client mix.
Can I change the design?
Colours, logo and address live in theme.json; copy lives in templates.js. Rebuild with one command.