A working example of @better-email/maizzle:
keep your Maizzle build — Tailwind, components, CSS
inlining — and emit a Better Email Design System from
it. Marketers get editable inputs; you keep your toolchain and your git
history.
Three modules (src/modules/), each a normal Maizzle HTML fragment with a
better: front-matter block declaring the inputs a marketer can edit:
---
better:
key: hero
name: Hero
settings:
- key: hero
name: Hero
inputs:
- key: heading
name: Heading
type: text
defaultValue: Build emails like software
---
<style>
@tailwind utilities;
</style>
<table role="presentation" class="w-full bg-[#0F1C2E]">
<tr>
<td align="center" class="px-8 py-12">
<h1 class="m-0 text-[32px] font-bold text-white">@{{ hero.heading }}</h1>
</td>
</tr>
</table>@{{ … }} is Maizzle's escape for a literal {{ … }}, which is how Liquid
placeholders survive the build. {% … %} tags pass through untouched.
npm install
npx better-maizzle build # compiles Tailwind, inlines CSS, emits ./betterThe better/ directory is a complete Design System in the
Better Email file format:
each module's utilities are compiled and inlined into style attributes
(fragments have no <head>, so nothing depends on a <style> block
surviving), and better/.better-maizzle-manifest.json tracks which modules
the build owns — hand-maintained modules pulled from the platform are never
touched.
Ship it with the Better Email CLI:
npm install -g @better-email/cli
better login
better ds pull <id> --dir better # bind the output to your Design System
npx better-maizzle build
cd better && better check && better ds pushsrc/modules/ your Maizzle fragments, one per module
better-src/ design-system.json, base.liquid, settings.json
(the non-module files, copied through verbatim)
better.maizzle.config.mjs
config.js your ordinary Maizzle config
The better-src/ files here are borrowed from
Meridian, the hand-authored starter
Design System — brand tokens live on the Global setting and are addressed as
@{{ global.color_brand }} etc. from any module.
MIT.