MJML Ruby Implementation
mjml-rb 0.6.0 is a pure-Ruby compiler targeting MJML 5.4.1.
The gem version and the upstream MJML version are separate. Node.js/npm is used
only for the development reference checks; compilation requires neither.
- Synchronous
mjml2htmllibrary API returning HTML, errors and warnings - Command-line interface (
mjml) - Rails integration (ActionView template handler for
.mjmlviews) - Validation (soft, strict, skip)
- Custom component support
- Pure Ruby parser, AST, validator, and renderer
- CSS inlining tested with
css_parser1.21, 2.x and 3.x
Full Usage Guide — API reference, all compiler options, component attribute tables, CLI flags, Rails setup, custom components, and more.
See the 0.6.0 release notes and changelog.
Installation
Requires Ruby >= 3.3, css_parser >= 1.17, < 4, and Nokogiri >= 1.13.
CI covers Ruby 3.3, 3.4 and 4.0 with css_parser 1.21, 2.x and 3.x.
# Gemfile
gem "mjml-rb", "~> 0.6.0"Quick Start
require "mjml-rb"
result = MjmlRb.mjml2html(<<~MJML)
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>Hello World!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>
MJML
puts result[:html] # compiled HTML
puts result[:errors] # validation errors (if any)
puts result[:warnings] # non-blocking issues in soft validationCLI
mjml email.mjml -o email.html # compile to file
mjml -r "templates/*.mjml" -o output/ # batch compile
mjml -v email.mjml # validate only
mjml -i -s < email.mjml # stdin → stdoutSee the Usage Guide — CLI section for all flags and config options.
Upgrading from mjml-rb 0.5.x (MJML v4)
The 0.6.x line uses v5 defaults. mj-include is silently omitted by default.
Enable local includes explicitly and supply the template's directory:
MjmlRb.mjml2html(source,
ignore_includes: false,
file_path: File.dirname(template_path),
actual_path: template_path
)For the CLI, use mjml email.mjml --config.allowIncludes -o email.html.
Includes stay within the template's canonical root and any explicit include_path
roots; absolute paths and escapes are denied.
mj-body now owns the HTML <body>, including its id and css-class.
Update CSS selectors that expected the class on the inner article. Background
painting below short emails can consequently change in browser previews.
minify takes precedence over beautify; raw whitespace and Outlook conditionals
are preserved, but formatted output can differ from earlier releases.
See the migration guide for the breaking changes and the compatibility audit for verified scope and limitations.
Rails
Add the gem to your Gemfile — that's it. The .mjml template handler is registered automatically.
<!-- app/views/user_mailer/welcome.html.mjml -->
<mjml>
<mj-body>
<mj-section>
<mj-column>
<mj-text>Welcome to our service!</mj-text>
</mj-column>
</mj-section>
</mj-body>
</mjml>class UserMailer < ApplicationMailer
def welcome(user)
mail(to: user.email, subject: "Welcome")
end
endRaw XML .mjml templates are compiled as supplied; embedded ERB is not evaluated.
For dynamic templates, load a Slim or Haml ActionView handler and set
config.mjml_rb.rails_template_language = :slim (or :haml). See the
Usage Guide — Rails section for examples.
Architecture
MJML string → Parser → AST → Validator → Renderer → Formatter → HTML
-
Parser — normalizes source, expands explicitly enabled
mj-include, produces a Nokogiri XML node tree - Validator — checks structure, hierarchy, and attribute types
- Renderer — resolves head metadata, applies defaults, emits responsive HTML
- Formatter — applies the selected formatting and CSS template checks
For the full internal walkthrough, see docs/ARCHITECTURE.md.
The compatibility audit records pinned upstream checks and maintainer-reported downstream Chrome comparisons. These are representative browser renders, not certification across email clients. Customer screenshots remain private; public examples use synthetic content.
Contributing
This is a fully open source project — feedback, bug reports, test cases, and pull requests are welcome! Feel free to use it in your projects and let me know how it goes.
Disclaimer
This is an unofficial Ruby port of the MJML email framework, not affiliated with or endorsed by the MJML team. Compatibility is checked against the pinned mjml@5.4.1 compiler. This port remains experimental: the parser, CSS inliner and formatter have documented differences, and identical rendering across all email clients is not guaranteed.
License
See LICENSE and third-party notices.