Hyper Elements vs MJML

Both write responsive emails that work in Outlook. Hyper Elements does it in React and TypeScript, checks every email, shows it in every email client, and renders it on-brand.

Hyper Elements vs MJML at a glance

What you get with each, side by side, if you’re weighing an MJML alternative.

FeatureHyper ElementsMJML
Accessibility lintYes18 rulesNo
Email client previewsYesOutlook, Gmail and moreNoBrowser preview
Email client support checksYesrender(), CLI, CINo
Brand theme with tokensYesdefineTheme()Partlymj-attributes
Variants from the themeYesvariant="secondary"Partlymj-class
Typed props, loops and conditionsYesTypeScriptNoAdd a templating language
Your own componentsYescomponent()Partlymj-include
Template checked when it rendersYesWith the fixPartlyTags and attributes
Plain-text versionYesNo
Agent skill and JSON CLIYesPartlyCLI
Local preview serverYesPartlyEditor extension
Visual editorYesDrag and drop (Unlayer)PartlyThird-party builders
Responsive tables that work in OutlookYesYes
Web pages, PDFs and imagesYesFrom one templateNoEmail only
Any email providerYesYes
Open source, MITYesYes

Included free

See it in Outlook, Gmail, Apple Mail and Yahoo Mail before you send

MJML shows your email in a browser at different widths. Hyper Elements shows you what Outlook, Gmail and Apple Mail do with it.

  • FreeNo account, key or limit
  • LocalNothing sent or uploaded
  • Light and darkDesktop and phones
  • FastAs long as a render
Apple Mail
Classic Outlook
Gmail app
  • Classic Outlook97%
  • Outlook.com99%
  • Outlook for Mac98%
  • Gmail99%
  • Gmail app98%
  • Apple Mail98%
  • Yahoo Mail99%
  • AOL Mail99%

Before you send

Every email checked, in code and in CI

Each render lists what classic Outlook, Gmail and the other clients will change, and a mistake stops it with what to write instead.

  • In your coderender() and validate() return them, with where each one is
  • In CIThe CLI's check exits 1 on an error, with --json for scripts
  • With the fixEach one says what to write instead, so an agent fixes it itself

MJML's validator checks its own tags and attributes, not what email clients will change.

How diagnostics work →
render(<LaunchEmail />).diagnostics
  • errorstyle/unknown"marginBottom" isn't a style a Text takes: use the parent's gap, or padding.
  • infoemail/outlook-degradedborderRadius on this Column in classic Outlook: square corners
  • infoemail/degradedhover on this Button in some email clients: no change (where it shows, keyboard focus gets it too)
  • infoemail/outlook-degradedletterSpacing on this Text in classic Outlook: normal spacing: Word keeps letter spacing but doesn't draw it

On brand, in every email

Write your brand once as a theme. The template names no colors or fonts; swap the theme and the same email is someone else's.

The same announcement email with the North theme
theme={north}North
The same announcement email with the Bloom theme
theme={bloom}Bloom
emails/announcement.tsx
<Email theme={north}>
  <Column style={{ apply: ["card"] }}>
    <Heading level={1}>The winter collection…</Heading>
    <Text>Everything you asked for…</Text>
    <Button href="…">Shop the drop</Button>
    <Button href="…" variant="secondary">
      See the lookbook
    </Button>
  </Column>
</Email>
  • TokensColors, fonts, sizes, spacing and corners, checked when the template is read
  • Defaults and variantsEvery Button, Heading and Divider styled once, with named versions
  • EverywhereThe same theme brands emails, pages, PDFs and images

MJML: defaults per component with mj-attributes and named groups with mj-class, with no tokens.

How themes work →

The same email in MJML and Hyper Elements

MJML has no variables: {{name}} is left for a templating language. In Hyper Elements it's a typed prop.

Hyper Elements 33s1,831 tokens

emails/welcome.tsx
import { Button, Column, Email, Heading, Section, Text } from "@hyper-elements/react";

export default function Welcome({ name }: { name: string }) {
  return (
    <Email
      width={520}
      previewText="Welcome to Orbit"
      style={{ backgroundColor: "#f3f4f6", fontFamily: "Helvetica, Arial, sans-serif" }}
    >
      <Section style={{ padding: [40, 0] }}>
        <Column style={{ backgroundColor: "#ffffff", borderRadius: 8, padding: 32, gap: 16 }}>
          <Heading style={{ fontSize: 24, color: "#101828" }}>
            Welcome, {name}
          </Heading>
          <Text style={{ fontSize: 16, color: "#4a5565" }}>
            Your workspace is ready.
          </Text>
          <Button
            href="https://example.com/start"
            style={{ backgroundColor: "#4f39f6", borderRadius: 6 }}
          >
            Open your workspace
          </Button>
        </Column>
      </Section>
    </Email>
  );
}

MJML 43s2,762 tokens

emails/welcome.mjml
<mjml>
  <mj-head>
    <mj-preview>Welcome to Orbit</mj-preview>
    <mj-attributes>
      <mj-all font-family="Helvetica, Arial, sans-serif" />
    </mj-attributes>
  </mj-head>
  <mj-body width="520px" background-color="#f3f4f6">
    <mj-section padding="40px 0">
      <mj-column background-color="#ffffff" border-radius="8px" padding="32px">
        <mj-text font-size="24px" font-weight="700" color="#101828" padding="0 0 16px">
          Welcome, {{name}}
        </mj-text>
        <mj-text font-size="16px" color="#4a5565" padding="0 0 16px">
          Your workspace is ready.
        </mj-text>
        <mj-button href="https://example.com/start" background-color="#4f39f6" border-radius="6px" align="left" padding="0">
          Open your workspace
        </mj-button>
      </mj-column>
    </mj-section>
  </mj-body>
</mjml>

Beyond email

Change a template's root and the same content becomes a web page, a PDF or an image.

Questions about switching from MJML

What are the alternatives to MJML?

The main ones are Hyper Elements, React Email and Maizzle. Hyper Elements and React Email write emails as React components; Hyper Elements also works out the layout, checks the email, previews it in email clients, keeps it on brand with a theme, and renders the same template as a page, a PDF or an image. Maizzle builds HTML emails with Tailwind CSS.

Which handles Outlook better, MJML or Hyper Elements?

Both write the tables and conditional comments classic Outlook needs, so you don't. Hyper Elements also works out every width in px before it writes anything, tells you what classic Outlook will show differently (square corners, say), and previews the email as classic Outlook draws it.

How do I put data in an email?

In Hyper Elements a template is a function: its props are typed, and loops and conditions are plain TypeScript. MJML has no variables, loops or conditions; its docs suggest adding a templating language such as Handlebars or Liquid.

Can I preview my MJML emails in Outlook and Gmail?

Yes, for free. Compile them to HTML and give it to Hyper Elements' email client emulator, @hyper-elements/email-clients, or paste it into the email testing playground. It previews classic Outlook, Outlook.com, Gmail, Apple Mail, Yahoo Mail and more on your machine, in light and dark mode, with no test sends or account.

Can I convert my MJML templates?

Not automatically yet: the migrate command converts React Email and Unlayer Elements templates. Your MJML emails' HTML works with the email client emulator as it is.

Do I need a React app to use Hyper Elements?

No. Templates are React components in TypeScript or JavaScript, but render() runs on your server and returns HTML and plain text, to send with any email provider. Nothing runs in the reader's browser.

Which is faster for a coding agent?

In our benchmark, Claude Code reached a passing email 1.3× faster with Hyper Elements than with MJML, writing 1.5× fewer output tokens, across five briefs and 16 runs each. Both passed the first check every time, and MJML was faster on one of the five emails. It's one agent and one model on short, fully specified emails. The harness is in the repository, so you can run it with your own agent.

Start with Hyper Elements

Install the package and write your first email, or keep your MJML emails and preview their HTML in every client for free.

Also compare: Hyper Elements vs React Email · React Email alternatives · MJML alternatives · Litmus alternatives