@better-email/maizzle
v0.1.0
Published
Build Better Email Design System trees from existing Maizzle projects.
Readme
@better-email/maizzle
Turn an existing Maizzle project into a Better Email Design System file tree.
Maizzle keeps doing the Tailwind compilation, component expansion, and CSS
inlining; the adapter adds stable Module metadata and files that better ds
push can ship.
Setup
Install the adapter and Maizzle 5 in the Maizzle project:
pnpm add -D @better-email/maizzle @maizzle/framework@^5Add better.maizzle.config.mjs:
export default {
modules: "src/modules/**/*.html",
designSystemDir: "better-src",
out: "better",
// maizzle: "./config.js",
};The values shown are the defaults. When maizzle is omitted, the adapter
loads config.js and overlays config.production.js when they exist.
Module builds default css.inline to true so utility styles survive in email
fragments. An explicit css.inline value in the Maizzle config wins; Maizzle
keeps CSS it cannot inline, such as media queries.
Tailwind replaces the content entry matching the adapter's Module glob with
each Module body independently. Other configured raw, file, and glob entries
remain as explicit extra content. Successfully inlined selectors and unused
rules are removed from the residual <style> block.
Run better-maizzle init to create that config, a minimal version 3 Design
System base in better-src/, and an example Module. It refuses to overwrite
existing files.
Module front matter
Keep each Module as a normal Maizzle HTML fragment and add a better YAML
block:
---
better:
key: hero
name: Hero
settings:
- key: hero
name: Hero
inputs:
- key: heading
name: Heading
type: text
defaultValue: Welcome
---
<table class="w-full">
<tr>
<td class="p-6 text-2xl">@{{ hero.heading }}</td>
</tr>
</table>Use Maizzle's @{{ ... }} escape when a Better Email Liquid output must
survive the build; the result is literal {{ ... }} in module.liquid.
Liquid tags such as {% if hero.heading %} pass through unchanged.
Responsive utilities such as sm:text-3xl remain in that Module's residual
<style> block for clients that honor embedded CSS. For broader email-client
support, define responsive helpers in the <head> of
better-src/base.liquid instead.
Module keys use lowercase underscore-separated identifiers. Module and
setting and input IDs are optional: missing IDs become mz_<moduleKey>,
mz_<moduleKey>_<settingKey>, and
mz_<moduleKey>_<settingKey>_<inputKey>. Explicit IDs are preserved when
adopting an existing server-side Module. Setting keys must be unique across
the Template Base and every Module; input keys must be unique within their
setting.
Build
Bind the output directory to the target Design System once, then build and push from that directory:
better ds pull <id> --dir better
better-maizzle build
(cd better && better push)Use better-maizzle build --quiet in automation to suppress the summary.
The build validates the complete output tree with the same serializer used by
better push before writing any files.
The build writes the documented Design System tree under better/ and records
its Module keys in better/.better-maizzle-manifest.json. It removes only
manifest-owned Modules that disappeared from the source glob; pulled and
hand-maintained Module directories survive. It never touches better/.better/
or unrelated files.
Publishing
Maintainers build and verify the standalone package, then publish it publicly:
pnpm run build:maizzle-package
npm publish dist/maizzle-package --access public