mjmlio/mjml
49.3
Weak · 1 October 2026
7.4k
lines of production code
JavaScript
primary language
2
measurements over time
What this system is
This system is the MJML framework, a tool for authoring responsive HTML emails using a semantic MJML markup language. It provides a core rendering engine that converts MJML templates into Outlook-compatible HTML, supported by a CLI for command-line processing and a browser bundle for client-side usage. The system includes a comprehensive suite of components for building email layouts, styling, and content, along with robust validation and security features to ensure template integrity.
How it got here
2016 — Monorepo restructuring and component implementation
31 changes.
The project underwent a significant architectural overhaul, migrating to a Lerna monorepo with modernized tooling and refactoring the core rendering engine to support explicit component registration. This period focused on rebuilding the library from the ground up, removing legacy class-based components, and implementing a comprehensive suite of new MJML components for layout, styling, and interactivity.
2017–2018 — Core refactoring and component expansion
13 changes.
This period focused on restructuring the MJML core rendering pipeline and XML parser into modular, single-purpose utilities to improve maintainability and security. It introduced a structured attribute validation system and new head-related components for managing breakpoints and preview text. Additionally, the mj-wrapper component was added with section gap support, while the CLI and accordion components received significant refactoring and testing enhancements.
2020–2026 — browser support and core simplification
6 changes.
This period focused on expanding MJML's runtime environments by introducing a dedicated browser bundle and Node.js-compatible stubs for client-side usage. It also streamlined the developer experience through a new core preset package that bundles standard components, reducing the need for individual registrations. Comprehensive test suites were added to ensure rendering accuracy and enforce security controls for features like includes and custom attributes.
Features
Add mj-breakpoint component to set email client breakpoint width
Introduces the new \mj-breakpoint\ head component, allowing users to explicitly define the breakpoint width (in pixels) used by responsive email clients. This component registers the specified width with the MJML core context, enabling consistent responsive behavior across different email clients.
packages/mjml-head-breakpoint/src · high confidence
Add mj-font component for defining custom fonts
A new mj-font component has been introduced, allowing users to define custom fonts within the MJML head section. By specifying the name and href attributes, this component registers the font resource, enabling its use in email templates.
packages/mjml-head-font/src · high confidence
Add mj-preview component for setting email preview text
Introduces the mj-preview component, which allows users to define the preview text (preheader) that appears in email clients alongside the subject line. This new component registers its content with the head section context under the 'preview' key, enabling email clients to display this summary text in the inbox view.
packages/mjml-head-preview/src · high confidence
Add mj-title component for setting email subject lines
The mjml-head-title package now includes an MjTitle component that allows users to define the title (subject line) of their email. This component extends HeadComponent and registers the content as the email title via the context's add method.
packages/mjml-head-title/src · high confidence
CLI now supports detailed configuration via --config JSON arguments
The MJML CLI now accepts a \--config\ (or \-c\) argument that takes a JSON object, allowing users to pass specific options directly from the command line. This includes granular control over \juiceOptions\, \minifyOptions\, \juicePreserveTags\, \fonts\, \templateSyntax\, and \includePath\. Relative paths in \includePath\ are now resolved against the current working directory rather than the template file's directory, providing more intuitive behavior for project structures. Additionally, the CLI exposes \keepComments\ and \allowIncludes\ settings, enabling users to fine-tune the compilation process without needing an external configuration file.
packages/mjml-cli/src · high confidence
Initial implementation of the mj-button component
The mjml-button package now includes a concrete implementation of the mj-button component, replacing the previous placeholder. This component renders a styled button using an HTML table structure for email client compatibility, supporting attributes for alignment, background color, border radius, padding, font styling, and link behavior (href, target, rel, title). It defaults to a centered, dark gray button with white text and includes accessibility features like role='presentation' and proper handling of the name attribute for links.
packages/mjml-button/src, packages/mjml-column/src, packages/mjml-table/src · high confidence
Initial implementation of the mj-image component with comprehensive attribute support
The mjml-image package introduces the core rendering logic for the mj-image component, defining its structure and styling. This implementation supports a wide range of attributes including accessibility features (alt, title, role=presentation), responsive behavior (fluid-on-mobile, width, height, max-height), and modern image standards (srcset, sizes). It also handles link wrapping with attributes like href, target, rel, and name, while managing border styles and padding to ensure consistent rendering across email clients.
packages/mjml-image/src · high confidence
Initial release of the MJML engine and CLI
This change introduces the core MJML engine, providing a command-line interface (CLI) and a JavaScript API to compile MJML templates into responsive HTML emails. The engine parses MJML documents, renders them using React, and applies specific CSS fixes and conditional comments to ensure compatibility with legacy email clients, particularly Outlook. The initial release includes built-in support for standard components such as body, button, column, divider, html, image, list, raw, section, social, and text, along with utilities for custom component registration and HTML minification.
src · high confidence
Introduce mj-carousel component for image slideshows
Adds the new \mj-carousel\ and \mj-carousel-image\ components, enabling users to create interactive image slideshows with navigation arrows and optional thumbnails. The carousel supports configurable alignment, border radius, icon styling, and thumbnail visibility modes (visible, hidden, or supported), with specific CSS handling for Outlook and other email clients to ensure compatibility.
packages/mjml-carousel/src · high confidence
Introduce mj-divider component with alignment and Outlook support
Adds the new mj-divider component, allowing users to insert horizontal rules with configurable border style, width, color, and padding. The component supports an align attribute (left, center, right) to position the divider and includes specific rendering logic for Microsoft Outlook via conditional comments to ensure correct width calculation and layout in that client.
packages/mjml-divider/src · high confidence
Introduce mj-group component for nested column layouts
Added the mj-group component, allowing users to nest columns within a group. This component manages container width calculations for its children, supports direction (ltr/rtl) and vertical alignment, and includes specific Outlook-compatible table structures with role presentation for accessibility.
packages/mjml-group/src · high confidence
Introduce mj-head component to handle head section processing
The mjml-head package now exports an MjHead component that extends the core HeadComponent. This component is responsible for processing the head section of MJML templates by delegating to its children, establishing the structural foundation for head-related elements like styles and metadata.
packages/mjml-head · high confidence
Introduce mj-navbar and mj-navbar-link components
This change adds the new \mj-navbar\ and \mj-navbar-link\ components to the MJML library. The \mj-navbar\ component provides a responsive navigation bar with support for hamburger menu toggling, customizable icon styles (open/close states), and alignment options. The \mj-navbar-link\ component allows for styled navigation links within the navbar, supporting attributes for typography, padding, and link behavior (such as \target\ and \rel\). These components are exported via the \mjml-navbar\ package index.
packages/mjml-navbar/src · high confidence
Introduce mj-raw component for embedding raw HTML
A new \mj-raw\ component has been added to the MJML library, allowing users to embed raw HTML content directly into their email templates. This component extends \BodyComponent\ and is configured to preserve the raw content via \getContent()\, support an optional \position\ attribute to control placement (specifically \file-start\), and handle ending tags correctly. It utilizes the \htmlparser2\ library for parsing, replacing the previous \node-expat\ dependency, and exposes the \isRawElement\ property to ensure proper handling within the rendering pipeline.
packages/mjml-raw/src · high confidence
Introduce mj-spacer component with configurable height
Added the mj-spacer component, which renders a vertical spacer using a div with a non-breaking space character. The component allows users to set the spacer's height via the 'height' attribute (defaulting to 20px) and supports various border and padding attributes for styling. It is implemented as a BodyComponent within the MJML core framework.
packages/mjml-spacer/src · high confidence
Introduce mj-wrapper component with section gap support
A new mj-wrapper component has been added, extending the existing mj-section to provide a configurable gap between sections via the new 'gap' attribute. The implementation handles Outlook-specific rendering by wrapping children in conditional comments and applying suffix CSS classes, ensuring consistent spacing and layout behavior across email clients.
packages/mjml-wrapper/src · high confidence
Introduce mjml-preset-core package for simplified MJML setup
A new \mjml-preset-core\ package has been added to bundle the core set of MJML components (such as body, head, section, column, button, image, text, and various layout elements) into a single preset. Users can now install this package and pass it to the \mjml2html\ function via the \presets\ option to enable all standard MJML components with a simple configuration, rather than registering them individually.
packages/mjml-preset-core · high confidence
Introduction of mj-attributes component for global styling
The mjml-head-attributes package now provides the mj-attributes component, allowing users to define global class definitions, default attributes for specific tags, and class-specific defaults within the MJML head. This enables centralized styling configuration that applies across the entire email template, replacing the need to repeat attribute definitions in individual elements.
packages/mjml-head-attributes/src · high confidence
Introduction of mj-social and mj-social-element components
This change introduces the core implementation for the social media icon block (\mj-social\) and its individual items (\mj-social-element\). The \Social\ component manages layout modes (horizontal or vertical) and passes shared styling attributes to its children. The \SocialElement\ component defines the structure for individual social links, including a built-in registry of default social networks (such as Facebook, Twitter/X, LinkedIn, etc.) with their respective icons and share URLs, while supporting customization of icons, text, colors, and accessibility attributes like alt and title.
packages/mjml-social/src · high confidence
Introduction of the mj-hero component
The mjml-hero package now provides the mj-hero component, allowing users to create hero sections with background images, colors, and padding. This new component supports fixed-height and fluid modes, includes Outlook-specific VML rendering for compatibility, and exposes attributes such as border-radius, vertical-align, and inner-padding to control the visual layout of the hero area.
packages/mjml-hero/src · high confidence
New mj-html-attributes component for custom HTML head attributes
Added a new mj-html-attributes component that allows users to define custom attributes for HTML elements within the document head. This component processes mj-selector children to map specific paths to custom attribute key-value pairs, enabling more granular control over the generated HTML head structure.
packages/mjml-head-html-attributes/src · high confidence
New mj-style component for head styles
A new mj-style component has been added to the MJML core library, allowing users to define styles in the document head. This component supports an 'inline' attribute; when set to 'inline', the styles are added to the inlineStyle collection, otherwise they are added to the standard style collection.
packages/mjml-head-style/src · high confidence
New mj-text component with height and letter-spacing support
The mjml-text package now includes a new MjText component that allows users to set the height of the text container using the 'height' attribute (supporting pixels and percentages) and add letter spacing via the 'letter-spacing' attribute (supporting negative values). The component also supports standard text styling attributes like font-family, font-size, color, align, and text-transform, with sensible defaults for font and padding.
packages/mjml-text/src · high confidence
New standalone MJML browser bundle package
A new \mjml-browser\ package has been introduced to allow MJML to be used directly in client-side environments. This package provides a UMD bundle that exposes the \mjml\ function globally, enabling users to convert MJML to HTML in the browser via \require('mjml-browser')\ or the global \window.mjml\. The build is configured to exclude Node.js-specific modules (like \fs\ and \path\) and features that rely on the file system, such as \mj-include\ tags and custom components defined in \.mjmlconfig\. The bundle is minified and optimized for browser consumption, with a smoke test ensuring the output is ASCII-only and functional.
packages/mjml-browser · high confidence
mj-section component gains comprehensive styling and layout controls
The mj-section component now supports granular styling and layout attributes, including individual border properties (border, border-top, border-bottom, border-left, border-right), border-radius, and a gutter attribute for spacing between columns. It also introduces full-width mode, explicit background positioning (x/y), and direction control (ltr/rtl). These changes allow users to create more visually complex and responsive email sections with precise control over borders, spacing, and background images.
packages/mjml-section/src · high confidence
Removals
Removal of legacy MJML React components and base classes
The \src/components\ directory has been completely cleared of all legacy MJML React components (including Body, Button, Column, Divider, Html, Image, List, Raw, Section, Social, and Text) and their base classes (MJMLElement, MJMLColumnElement). This change removes the old class-based component implementation from this location, indicating a migration to a different rendering architecture or component structure elsewhere in the codebase.
src/components · high confidence
Security
Secure MJML XML parser with strict include path validation
The MJML XML parser now enforces strict security controls on file includes. It validates that included files reside within allowed directories (current working directory or specified include paths), rejecting absolute paths, UNC paths, drive letters, and null bytes to prevent directory traversal attacks. The parser also supports including HTML and CSS files, handles URL-encoded paths, and provides clear error messages when includes are denied or fail to read.
packages/mjml-parser-xml/src · high confidence
Behavioural changes
Added 'inherit' to the list of valid color values
The MJML core library now recognizes 'inherit' as a valid color value. This change allows users to explicitly set color attributes to inherit their value from a parent element, expanding the supported color options beyond standard named colors and hex codes.
packages/mjml-core/src/types/helpers · high confidence
Browser-safe stubs for Node-specific modules
The mjml-browser package now includes a set of mock modules (empty, fs, htmlnano, minify, mjmlconfig, skeleton-loader) to replace Node.js-specific dependencies in browser environments. These stubs prevent build errors by providing safe, no-op, or browser-compatible implementations for file system access, HTML minification, and configuration loading, ensuring the library runs correctly in client-side contexts without relying on server-side APIs.
packages/mjml-browser/browser-mocks · high confidence
CLI entry point now delegates to client module
The MJML CLI executable script has been updated to directly require and invoke the client module from the lib directory, establishing the primary entry point for command-line operations.
packages/mjml-cli/bin · high confidence
CLI entry point now delegates to mjml-cli
The \mjml\ binary in the \packages/mjml/bin\ directory has been updated to directly require and execute the client module from the \mjml-cli\ package. This change centralizes the command-line interface logic within the dedicated CLI package, ensuring that running the \mjml\ command invokes the standardized CLI implementation rather than any previous inline or alternative logic.
packages/mjml/bin · high confidence
Core MJML processing is now delegated to mjml-core with preset wiring
The main entry point for MJML has been refactored to act as a thin wrapper around the new \mjml-core\ package. Instead of containing the full processing logic, the \mjml2html\ function now imports the core processor and the core preset, explicitly assigns the preset's components and dependencies to the global registries, and delegates the actual conversion to \mjml2htmlCore\. This change centralizes the rendering engine in \mjml-core\ while maintaining the public API surface for users.
packages/mjml/src · high confidence
Core rendering engine and component registration refactored
The mjml-core package has been restructured to improve how components are registered and how the MJML-to-HTML pipeline processes templates. A new component registry system (components.js) allows for explicit registration of components and their dependencies, replacing previous implicit mechanisms. The core rendering logic (createComponent.js, index.js) has been refactored to support sibling elements in renderMJML, better handling of head styles, and improved attribute formatting. Additionally, the skeleton loading mechanism is now isolated in a node-specific module (skeleton-loader.js) to support isomorphic usage, and the main index.js now includes robust sanitization for CSS variables and inline styles to prevent injection issues during the minification and inlining process.
packages/mjml-core/src · high confidence
Introduce structured attribute type validation system
The \packages/mjml-core/src/types\ directory now implements a dedicated type system for validating MJML attribute values. This change adds specific validators for boolean, color, enum, integer, string, and unit types, replacing or augmenting previous ad-hoc validation logic. Users will benefit from more precise error messages and stricter validation rules, such as support for negative values in unit attributes (via \unitWithNegative\), handling of 'auto' in unit validation, and improved color format normalization (e.g., shorthand hex expansion). The \index.js\ file registers these types, making them available for attribute processing within the core.
packages/mjml-core/src/types · high confidence
MJML Accordion component restructured with new styling and fallback logic
The mj-accordion package has been refactored to improve rendering consistency and styling control. The component now explicitly sets cellspacing and cellpadding to 0 on generated tables to prevent unwanted spacing in email clients. Additionally, the mj-accordion-title and mj-accordion-text components now support a font-weight attribute, and their font-family resolution logic has been updated to correctly inherit from parent context or fall back to defaults if not explicitly defined.
packages/mjml-accordion/src · high confidence
Project tooling and configuration overhaul
The repository has been restructured with significant changes to its development tooling and configuration. Prettier has been introduced as the code formatter (replacing the previous setup), with a new \.prettierrc\ and \.prettierignore\ file. ESLint configuration has been updated to extend \airbnb-base\ and \prettier\, removing legacy React-specific rules and adjusting linting rules. The build system has migrated from \.babelrc\ to \babel.config.js\ targeting Node 10, and the project is now managed via Lerna v9 with Yarn workspaces. Additionally, standard documentation files (CONTRIBUTING.md, LICENSE.md) and a manual test script (test.js) have been added.
(repo-wide) · high confidence
Refactor CLI helper logic and introduce default options
The CLI's internal helper structure has been reorganized: a new \defaultOptions.js\ file now centralizes default settings for beautification and minification, while \fileContext.js\ has been rewritten to handle file path resolution and include tracking. This refactoring improves how the CLI resolves nested includes and handles directory-based file paths, ensuring more robust dependency tracking for watch mode and file generation.
packages/mjml-cli/src/helpers · high confidence
Refactor XML parser helpers to clean nodes and normalize attributes
The XML parser's helper logic has been restructured into three distinct modules: cleanNode now recursively removes parent references and prunes empty children or attributes from the node tree; convertBooleansOnAttrs ensures that string values 'true' and 'false' in attributes are converted to actual boolean types; and setEmptyAttributes guarantees that every node has an attributes object initialized, preventing undefined errors during processing.
packages/mjml-parser-xml/src/helpers · high confidence
Refactored CLI output and file-watching logic
The CLI's output and file-watching mechanisms have been restructured into dedicated modules. Output to the console now supports an optional file header comment and uses \process.stdout.write\ for reliable flushing. File output logic has been extracted to handle path guessing, extension replacement, and directory detection. The file-watching system now uses \chokidar\ to monitor glob patterns, dynamically synchronizing watched files based on MJML includes and handling compilation with configurable minification and beautification.
packages/mjml-cli/src/commands · high confidence
Refactored core HTML generation and helper utilities
The \packages/mjml-core/src/helpers\ directory has been restructured into a set of dedicated, single-purpose modules to improve code maintainability and clarity. This change introduces specific helpers for generating Outlook conditional comments (\conditionalTag.js\), managing font imports (\fonts.js\), parsing CSS shorthand and borders (\shorthandParser.js\), and handling HTML beautification (\formatHtml.js\). It also adds dedicated logic for resolving custom component paths from \.mjmlconfig\ files (\mjmlconfig.js\), building media queries for various email clients (\mediaQueries.js\), and constructing the final HTML skeleton (\skeleton.js\). By extracting these concerns from monolithic files into granular utilities, the core rendering pipeline becomes more modular and easier to test.
packages/mjml-core/src/helpers · high confidence
Revamped MJML validation rules with improved error reporting
The validator has been refactored to provide more precise and user-friendly error messages. New rules now validate tag existence, attribute legality (with whitelisting for generic attributes like mj-class), and child element hierarchy, including support for regex-based dependencies. Type checking for attributes is enforced via a new type system, and error messages now include file path and line number context, including inclusion chains, to help users locate and fix issues in their MJML templates.
packages/mjml-validator/src/rules · high confidence
Validator now supports custom rule registration and dependency merging
The MJML validator has been refactored to allow users to register custom validation rules via the new \registerRule\ function and to merge dependency configurations using \registerDependencies\ and \assignDependencies\. This change enables extending the validation logic beyond the built-in rules (such as \validAttributes\, \validChildren\, and \validTag\) and allows dependency lists to be combined rather than overwritten, providing greater flexibility in how validation rules and their associated dependencies are configured.
packages/mjml-validator/src · high confidence
mj-body component restructured with accessibility and preview support
The mj-body component has been refactored to improve accessibility and developer experience. It now renders a wrapper div with ARIA attributes (role='article', aria-roledescription='email') and supports language (lang) and direction (dir) attributes for better screen reader support. A new preview helper injects hidden content for email clients that do not support certain features. The component also exposes container width via context for child components and enforces specific allowed attributes (width, background-color, id) with default width of 600px.
packages/mjml-body/src · high confidence
Test coverage
Added CLI packaging smoke test; Added unit tests for core MJML helper functions; Expanded test coverage for MJML components and security features; Initial test suite for MJML XML parser; Removal of legacy input-output test suite; Removed test assets for body and section components.
Dependencies
MJML 5.4.1 monorepo release with updated dependencies
This change updates the MJML framework to version 5.4.1 across all packages in the monorepo. It upgrades core dependencies including Babel to version 7.28.x, Lodash to 4.17.21, and PostCSS to 8.5.28, while also updating the CLI to use Yargs 17.7.2 and Glob 13.0.6. The root package.json is restructured to use Lerna for workspace management, replacing older build tools and scripts with modern equivalents like ESLint 7 and Mocha 10.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings — which rule fired, in which file, on which line, and how to fix it — are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.
Score
- CAI 52 → 49 (-3.1)
- Rubric changed (rubric-2026.09.11 → rubric-2026.09.18) — scores are not directly comparable.
Lenses
- Code Health 56 → 52 (-3.9)
- Architecture 96 → 97 (+1.2)
- Maturity 62 → 64 (+1.4)
- Readiness 64 → 42 (-22.0)
- Security 42 → 51 (+9.7)
- Performance 60 (new)
Resolved (7)
- Dependency hygiene PARTLY measured — npm pinning read, dependency currency not (no pnpm-resolved versions to grade)
- Documentation: no architecture or design documentation (README.md)
- Documentation: no contributor guidance (README.md)
- Documentation: no installation or build instructions (packages/mjml-core/README.md)
- Hotspot: packages/mjml-core/src/index.js (packages/mjml-core/src/index.js)
- Hotspot: packages/mjml-section/src/index.js (packages/mjml-section/src/index.js)
- Off-boarding risk: anonymized user #1
New (17)
- Coverage not measured — JavaScript/TypeScript suite
- High CVE: [GHSA redacted] (yarn.lock)
- High CVE: [GHSA redacted] (yarn.lock)
- High CVE: [GHSA redacted] (yarn.lock)
- Medium: security finding (details withheld)
- Medium: security finding (details withheld)
- Medium: security finding (details withheld)
- Off-boarding risk: anonymized user #1
- Outdated (npm): @babel/runtime
- Outdated (npm): chokidar
- Outdated (npm): cssnano
- Outdated (npm): cssnano-preset-lite
- Outdated (npm): htmlnano
- Outdated (npm): htmlparser2
- Outdated (npm): juice
- Outdated (npm): yargs
- Unstable project mjml-preset-core
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
mjmlio/mjml was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 1 October 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 1c434fcbfd042ddfcb9fa4e0496f7eedf1d90bc7 — the exact code this score is about.
- Scored under rubric-2026.09.18 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-e569280dd5e2.