Skip to main content

mjml-python

Compile MJML at runtime without a Node.js service, external API, or subprocess.
mjml-python is a Python wrapper around the Rust MJML engine MRML, a high-performance port of the official MJML.

Why

Using MJML traditionally requires either:

  • running the Node.js-based MJML CLI as a subprocess, or
  • calling an external MJML API service.

Both approaches add memory overhead, latency, operational complexity, and cost.

From MRML:

A Node.js server rendering an MJML template takes around 20 MB of RAM at startup and 130 MB under stress test. In Rust, less than 1.7 MB at startup and a bit less that 3 MB under stress test. The Rust version can also handle twice as many requests per second.

By embedding the Rust engine directly, mjml-python avoids all external dependencies while retaining full MJML compatibility.

Installation

Install from PyPI:

pip install mjml-python

Usage

Call mjml2html() with your MJML string:

from mjml import mjml2html

html = mjml2html(
    '''
        <mjml>
          <mj-body>
            <mj-section>
              <mj-column>
                <mj-image width="100px" src="/assets/img/logo-small.png"></mj-image>
                <mj-divider border-color="#F45E43"></mj-divider>
                <!-- Say hello to the user -->
                <mj-text font-size="20px" color="#F45E43" font-family="Open Sans">Hello World</mj-text>
              </mj-column>
            </mj-section>
            <mj-section>
              <mj-column>
                <mj-social font-size="15px" icon-size="30px" mode="horizontal">
                  <mj-social-element name="facebook" href="https://mjml.io/">
                    Facebook
                  </mj-social-element>
                  <mj-social-element name="google" href="https://mjml.io/">
                    Google
                  </mj-social-element>
                  <mj-social-element  name="twitter" href="https://mjml.io/">
                    Twitter
                  </mj-social-element>
                </mj-social>
              </mj-column>
            </mj-section>
          </mj-body>
        </mjml>
    ''',
    disable_comments=True,
    social_icon_origin="https://example.com",
    fonts={
        "Open Sans": "https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,700",
        "Ubuntu": "https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700",
    }
)

Example using Django templates

from django.core.mail import send_mail
from django.template.loader import render_to_string
from mjml import mjml2html

context = {'foo': 'bar'}
text_message = render_to_string('my_text_template.txt', context)
html_message = mjml2html(render_to_string('my_mjml_template.mjml', context))
send_mail(
    'Subject here',
    text_message,
    'from@example.com',
    ['to@example.com'],
    fail_silently=False,
    html_message=html_message,
)

Configuration Options

mjml-python supports the following options:

Name Type Default value Comment
disable_comments bool False Strip comments out of rendered HTML
social_icon_origin str | None None Custom URL origin for social icons. Icon name is appended (e.g. facebook.png).
fonts dict[str, str] | None None Fonts imported in the HTML rendered by MJML.
include_loader Callable[[str], str] | None None Fetch the included template using the path attribute.

Default fonts (used when fonts=None):

{
    "Open Sans": "https://fonts.googleapis.com/css?family=Open+Sans:300,400,500,700",
    "Droid Sans": "https://fonts.googleapis.com/css?family=Droid+Sans:300,400,500,700",
    "Lato": "https://fonts.googleapis.com/css?family=Lato:300,400,500,700",
    "Roboto": "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700",
    "Ubuntu": "https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700",
}       

Why choose mjml-python instead of other MJML packages?

  • Simple, Pythonic API – a single mjml2html() function that takes plain keyword arguments and returns a clean HTML string. No need to construct parser/render option objects or work with custom result classes.

  • Batteries-included defaults – sensible defaults for fonts, comment handling, and include behavior, so most templates work with zero configuration.

  • Flexible include loader – pass a Python callable to handle <mj-include> however you like (filesystem, database, HTTP, etc.) without learning MRML’s multiple loader types.

  • Minimal surface area – intentionally focused on the common case: take MJML input → return production-ready HTML. No extra abstractions.

  • No external services or subprocesses required – rendering is performed entirely inside the Python extension using the embedded Rust MJML engine. No Node.js installation, MJML CLI, or HTTP API needed.

  • Stable wheel builds – lightweight ABI-3 wheels for all major platforms (CPython 3.8+), fast installation, and no compilation required on typical environments.

In short: mjml-python is ideal when you want a straightforward, Python-friendly way to render MJML without dealing with the full MRML configuration surface or external tooling.

Development

With Nix:

nix-shell

With Python 3.8+, uv, Rust 1.83+ and Cargo installed:

uv sync --locked --no-install-project
uv run --locked --no-sync maturin develop
uv run --locked --no-sync python -m unittest

Metadata

Release files for mjml-python 1.4.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mjml-python 1.4.2
File Size Uploaded
mjml_python-1.4.2.tar.gz 18.0 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for mjml-python 1.4.2
File
mjml_python-1.4.2-cp38-abi3-win_amd64.whl CPython 3.8 abi3 Windows x86-64 Details
mjml_python-1.4.2-cp38-abi3-musllinux_1_2_x86_64.whl CPython 3.8 abi3 Linux musl 1.2+ x86-64 Details
mjml_python-1.4.2-cp38-abi3-musllinux_1_2_aarch64.whl CPython 3.8 abi3 Linux musl 1.2+ ARM64 Details
mjml_python-1.4.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.8 abi3 Linux glibc 2.17+ x86-64 Details
mjml_python-1.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.8 abi3 Linux glibc 2.17+ ARM64 Details
mjml_python-1.4.2-cp38-abi3-macosx_11_0_arm64.whl CPython 3.8 abi3 macOS 11.0+ ARM64 Details
mjml_python-1.4.2-cp38-abi3-macosx_10_12_x86_64.whl CPython 3.8 abi3 macOS 10.12+ x86-64 Details

Total release size: 4.3 MB

Release files / mjml_python-1.4.2.tar.gz

Download URL mjml_python-1.4.2.tar.gz
Size 18.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a3b10d0325653e85a7d2c4180ebc521141bedc0944c9a334d075151500b252b5
BLAKE2b-256 checksum
How to use checksums
d95020c4f6d8ce095317b3bad5e287ba2131e9e43fb8db1a2744b5a3bc5d1119
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-win_amd64.whl

Download URL mjml_python-1.4.2-cp38-abi3-win_amd64.whl
Size 451.0 kB
Tags CPython 3.8 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
e4df81e22e5c9d93a9b799fd7eb2a9f1eba5edbc02efb43804de5a2a50d683e0
BLAKE2b-256 checksum
How to use checksums
2ac7518db6d835daaeb85608714a35cb738dd1a4e871b2b6d840a0f6c6c9bf76
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-musllinux_1_2_x86_64.whl

Download URL mjml_python-1.4.2-cp38-abi3-musllinux_1_2_x86_64.whl
Size 701.4 kB
Tags CPython 3.8 Linux musl 1.2+ x86-64 abi3
SHA-256 checksum
How to use checksums
e3cb288724e89125a9735e367345d01bdf4d1ac57e973650cb9c7929885fb7d3
BLAKE2b-256 checksum
How to use checksums
3891b5e3606fbc61a0c05c3c9aa7ab3a7e2c8c2c79800c3179a154458cfd2611
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-musllinux_1_2_aarch64.whl

Download URL mjml_python-1.4.2-cp38-abi3-musllinux_1_2_aarch64.whl
Size 793.4 kB
Tags CPython 3.8 Linux musl 1.2+ ARM64 abi3
SHA-256 checksum
How to use checksums
355bedef9e3d858425ca4664cd8f16849341db6abc15b351a846f12ec687db27
BLAKE2b-256 checksum
How to use checksums
75c4d5e398455bc1295d35674c848391f0c461bb8dcb65d83b307f5d4bcd1afd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL mjml_python-1.4.2-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 611.7 kB
Tags CPython 3.8 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
6d05b2b86679e6539b6eb63b027a56870af2e08b63c67bdddaaff2d532e6088d
BLAKE2b-256 checksum
How to use checksums
ec41336a9a2d112662b4ded8d135573feda15fa67e2307fc8e8591be7b0ee939
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL mjml_python-1.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 616.8 kB
Tags CPython 3.8 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
0e91e925a2fc6324dc39fe7b500166d3480e70e00f13b2c3bb78b1953f887c45
BLAKE2b-256 checksum
How to use checksums
87337d2fd059e99e38f813ea3682c5aa379dfe3c6587659c103a81e195964351
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-macosx_11_0_arm64.whl

Download URL mjml_python-1.4.2-cp38-abi3-macosx_11_0_arm64.whl
Size 548.8 kB
Tags CPython 3.8 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
0a79b021110ea36b5f86a57c3f95a38f0b94f32b8c5fc421b672783c7fc8e06c
BLAKE2b-256 checksum
How to use checksums
4b7009a519382e58aae8894c0213210339d5d5649f52db84ba499c99fb90dab3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release files / mjml_python-1.4.2-cp38-abi3-macosx_10_12_x86_64.whl

Download URL mjml_python-1.4.2-cp38-abi3-macosx_10_12_x86_64.whl
Size 551.4 kB
Tags CPython 3.8 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
29342a947af5a578cf30ed1802726e5ed71e7226a13af6b16030164ad836fde5
BLAKE2b-256 checksum
How to use checksums
6115e05e37b710b874b905afc0fa1f31e31c0262450a3f24620e93fa6d50a286
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 1, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.4.2 This release

8 release files

1.4.1

8 release files

1.4.0

8 release files

1.3.7

7 release files

1.3.6

7 release files

1.3.5

7 release files

1.3.4

6 release files

1.3.3

6 release files

1.3.2

6 release files

1.3.1

6 release files

1.3.0

6 release files

1.2.4

6 release files

1.2.3

44 release files

1.2.1

29 release files

1.0.0

18 release files

0.1.0

18 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page