mrml
A fast, memory-efficient Rust reimplementation of the MJML email markup renderer
Repository Health
Technical Analysis
mrml is a Rust implementation of MJML, the responsive email markup language originally built as a Node.js tool by Mailjet. It parses .mjml templates and renders them to cross-client-compatible HTML, exposing the same component model (mj-section, mj-column, mj-button, etc.) developers already know from MJML.
The project exists primarily for performance and footprint: the README reports the Rust version needs under 2MB of RAM versus around 20MB for the Node.js renderer, and renders roughly 170x faster in the authors’ benchmark. Beyond the core Rust crate, the workspace ships a CLI, a WebAssembly build (so MJML can be rendered directly in a browser, which the Node.js implementation cannot do), and Python bindings via PyO3, making it usable well outside the Rust ecosystem.
What You Get
- A
parse/renderAPI covering the full MJML component set (mj-section, mj-column, mj-button, mj-image, mj-social, mj-carousel, mj-accordion, and more) - Pluggable include loaders (memory, local filesystem, HTTP — sync and async) for resolving
mj-includepartials - A WebAssembly build that renders MJML directly in the browser, something the original Node.js MJML cannot do
- A standalone
mrml-clibinary for rendering templates from the command line without writing any Rust - Python bindings (published as the
mrmlPyPI package) so non-Rust teams can call the same renderer - Feature flags to opt in/out of parsing, printing, rendering, async support, and specific HTTP loader backends, keeping the compiled binary lean
Common Use Cases
- Rendering transactional or marketing email HTML server-side in a Rust backend without shelling out to Node.js
- Embedding an MJML renderer in a browser-based email template editor via the WebAssembly build
- Replacing a Node.js MJML rendering microservice with a lower-memory Rust or WASM equivalent under high request volume
- Calling MJML rendering from Python services via the mrml Python bindings instead of maintaining a separate Node.js toolchain
Under The Hood
Architecture - The workspace splits into mrml-core (the parser/renderer library, one Rust module per MJML component such as mj_section, mj_column, mj_button), mrml-cli, mrml-wasm, and mrml-python, all depending on the core crate. Parsing goes through a prelude::parser layer that builds an AST of component structs, and rendering goes through a matching prelude::render layer that walks the same tree to emit table-based HTML; mj-include resolution is abstracted behind a loader trait with memory, local, and HTTP implementations (sync and async) so template inclusion isn’t tied to the filesystem. Tech Stack - Pure Rust with htmlparser for the base parsing, serde/serde_json behind the optional json feature, thiserror for typed errors, and enum_dispatch/enum-as-inner for the component enum dispatch; async HTTP loading is feature-gated behind reqwest or ureq backends and async-trait, keeping the default build free of an async runtime dependency. Code Quality - The crate is organized as one directory per MJML tag with colocated tests; the repo has 125+ files containing #[test], and CI badges (codecov, GitHub Actions) in the README indicate an established test and coverage pipeline. Feature flags (parse, render, print, json, async, per-loader flags) are used consistently to keep unused functionality compiled out. API Design - The top-level mrml::parse/parse_with_options functions plus element.render(&opts) give a minimal two-call happy path, and the same primitives are re-exposed nearly unchanged in the Python bindings (mrml.to_html), so the developer experience is consistent across the Rust, WASM, and Python entry points.
Used by 2 apps in this directory
DefGuard
Security · Networking · Authentication
Self-hosted secure remote access that unifies WireGuard VPN, identity management, and connection-level MFA in one open-source platform.
Hook0
Devops
Open-source Webhooks-as-a-Service: deliver events to your users with auto-retry, signed payloads, and a real-time subscriber dashboard — all without building the infrastructure yourself.