5 releases

0.1.4 Mar 21, 2024
0.1.3 Mar 21, 2024
0.1.2 Dec 4, 2023
0.1.1 Dec 1, 2023
0.1.0 Feb 12, 2023

#689 in Procedural macros

Download history 2562/week @ 2024-03-14 2870/week @ 2024-03-21 2225/week @ 2024-03-28 2563/week @ 2024-04-04 2698/week @ 2024-04-11 1943/week @ 2024-04-18 2121/week @ 2024-04-25 2207/week @ 2024-05-02 2306/week @ 2024-05-09 2764/week @ 2024-05-16 2666/week @ 2024-05-23 3146/week @ 2024-05-30 2615/week @ 2024-06-06 2433/week @ 2024-06-13 2328/week @ 2024-06-20 1713/week @ 2024-06-27

9,678 downloads per month
Used in 5 crates (3 directly)

MIT license

145 lines


Crates.io Crates.io FOSSA Status

.github/workflows/main.yml codecov

Average time to resolve an issue Percentage of issues still open Maintainability


This project is a reimplementation of the nice MJML markup language in Rust.

How to use it in my code

Update your cargo.toml:

mrml = "2"
serde = { version = "1.0", features = ["derive"] }

Create your main.rs:

use mrml;

fn main() {
    let root = mrml::parse("<mjml><mj-body></mj-body></mjml>").expect("parse template");
    let opts = mrml::prelude::render::Options::default();
    match root.render(&opts) {
        Ok(content) => println!("{}", content),
        Err(_) => println!("couldn't render mjml template"),

Available options are:

Name Comment Default value
disable_comments Strip comments out of rendered HTML false
social_icon_origin Custom URL for fetching social icons None
fonts Default fonts imported in the HTML rendered by MJML See default options


  • 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. You can perform the benchmarks by running bash script/run-bench.sh.
  • The JavaScript implementation cannot be run in the browser; the Rust one (and WebAssembly one) can be.

You want to contribute?

Feel free to read our contributing section and the code of conduct.


With the same Linux amd64 machine, to render the amario template

  • Node: 606.59ms
  • Rust: 3.48ms

Missing implementations

  • mj-style[inline]: not yet implemented. It requires parsing the generated html to apply the inline styles afterward (that's how it's done in mjml) which would kill the performances. Applying it at render time would improve the performance but it would still require to parse the CSS.
  • mj-include: not yet implemented. It requires to handle loading remote templates when using mrml in a wasm (browser or server side) format, which implies being able to load from a different location (file://, https://, relative, etc).

Who is using MRML?

If you are using MRML and want to be added to this list, don't hesitate to create an issue or open a pull request.

What is using MRML?

mjml_nif - Elixir library

mrml-ruby - Ruby library

mjml-python - Python library

If you are using MRML and want to be added to this list, don't hesitate to create an issue or open a pull request.

You want to sponsor us?

Buy Me A Coffee

Thanks to zachzurn.


FOSSA Status


~17K SLoC