Skip to main content

A Python wrapper for MRML (Rust port of MJML).

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mjml_python-1.4.1.tar.gz (17.8 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

mjml_python-1.4.1-cp38-abi3-win_amd64.whl (435.6 kB view details)

Uploaded CPython 3.8+Windows x86-64

mjml_python-1.4.1-cp38-abi3-musllinux_1_2_x86_64.whl (684.3 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ x86-64

mjml_python-1.4.1-cp38-abi3-musllinux_1_2_aarch64.whl (772.9 kB view details)

Uploaded CPython 3.8+musllinux: musl 1.2+ ARM64

mjml_python-1.4.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (599.9 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ x86-64

mjml_python-1.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (596.3 kB view details)

Uploaded CPython 3.8+manylinux: glibc 2.17+ ARM64

mjml_python-1.4.1-cp38-abi3-macosx_11_0_arm64.whl (542.7 kB view details)

Uploaded CPython 3.8+macOS 11.0+ ARM64

mjml_python-1.4.1-cp38-abi3-macosx_10_12_x86_64.whl (552.2 kB view details)

Uploaded CPython 3.8+macOS 10.12+ x86-64

File details

Details for the file mjml_python-1.4.1.tar.gz.

File metadata

  • Download URL: mjml_python-1.4.1.tar.gz
  • Upload date:
  • Size: 17.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mjml_python-1.4.1.tar.gz
Algorithm Hash digest
SHA256 b6f577e262f5caefbaec8ae15abcb90a8d2fe02ed089fc97852fd05b927a7f23
MD5 c251bef71ec8e1ce1ff9855bb2d0a197
BLAKE2b-256 abd00362ad0cd978006af2576f590969d2166f7bc98793a34a9bf6c2594d7f39

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1.tar.gz:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-win_amd64.whl.

File metadata

  • Download URL: mjml_python-1.4.1-cp38-abi3-win_amd64.whl
  • Upload date:
  • Size: 435.6 kB
  • Tags: CPython 3.8+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 bdf58eb4531506ac7b3192388aa834a1947024a4f547d3b23ff7db51a287759c
MD5 430704731dd1b4e6433e3af612e8a880
BLAKE2b-256 40a8974c4cdec35fdd84c429fd50ed77b5a997011102a94636745a0d001a9aa8

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-win_amd64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 247ed6a224ed238febc3c729f3bb67ff70ffdf9627e934d5122a62307c62bf7a
MD5 09ef3783a8bff481fb75b5efe5485886
BLAKE2b-256 5dbf56ab3d2e89a34d26c7f66e00472d03be6654ec66b085d30c9e92dfa84baa

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-musllinux_1_2_x86_64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ea0721657841cbb35bb3796cd1ffe93eaaa432ff5f10f18779abc8058172e068
MD5 4a8fdc1ac09e01caa5d19dbd506d6124
BLAKE2b-256 db04fe95834e46afe2e0311cff2f94c822e9babdc3cb6849e9eb80748e7fd32e

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-musllinux_1_2_aarch64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 5a92ef461bae751043eae787e07d4c2f25a71e36379a6b2c0c15fc4d59f100e5
MD5 1d197a42a9823ac9d17945cc533edc46
BLAKE2b-256 5bedb91433d8ee3bacb90c5d685ad64a6fe3969aad5f331213c95c0013ecaf51

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 38dcfe71383499455d3b6df7d1eabc4909e84de87f1e5c513d8bc5cda6ceba73
MD5 e651c75d68ca8294a0e4002520fae560
BLAKE2b-256 848909b64bd861622a499899ee6ef8b4d2a887956d8f49e2520e394838a1245f

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2080a59a4a98c9a3c9f663f4d194f0dddf807036cb33cf8a13e933637eb88921
MD5 f5f05891d67b2076a0985f29abeb4aa4
BLAKE2b-256 0ac4aa234971b108277610060e1aa7c26bf5339db96e37fa1d4aacd32be794d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-macosx_11_0_arm64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file mjml_python-1.4.1-cp38-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for mjml_python-1.4.1-cp38-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 b2acfb094fd4cdcbea0337a0f2a030ff8f5575bc4946b4ee8bdbd9a5ac372ae6
MD5 c6b394d461dd7201f7c8cf837688afaa
BLAKE2b-256 cc306d08fe76173daba651a391b0fee0f57fc0b73f50eee07fb0cf8146d44136

See more details on using hashes here.

Provenance

The following attestation bundles were made for mjml_python-1.4.1-cp38-abi3-macosx_10_12_x86_64.whl:

Publisher: Publish.yml on mgd020/mjml-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page