Your email design system, as code
The standoff
You already have a workflow you like
Every email platform asks you to give it up and move into their web editor. This one doesn't.
What you refuse to give up
- Git, branches, and pull requests
- Your editor, your keybindings, your dotfiles
- Hot reload on save
- CI that blocks bad changes
- Diffs you can actually read
What your org actually needs
- Modules marketers can safely fill in
- Safe rollouts that can’t break in-flight campaigns
- Review, approvals, and localization
- One-click export to the ESP
- A visual editor that never breaks the brand
Until now, connecting the two meant pasting HTML into a web editor, then pasting again after every change. Design Systems as Code splits the job instead: code owns structure, cloud owns content. You keep your loop. They keep theirs.
The format
It's just files
A Design System is a directory. The directory is the source of truth.
The file no framework has
Maizzle ends at HTML. settings.json is where a coded module becomes something a marketer can safely fill in: typed inputs, conditional visibility, repeatables, feed bindings. You declare them in code, next to the markup they control.
Plain Liquid and JSON
Grep it, diff it, vendor it, refactor it with sedif that's your thing. No binary blobs, no lock-in.
JSON Schemas, published
Every file has a $schema. Autocomplete and inline validation in your IDE, no compile step, and agents can read the spec.
Byte-identical round-trips
pull then push with no edits changes nothing, byte for byte. The serializer is property-tested against production design systems.
Rather read a real one? Meridian is a complete starter Design System in this format: 12 production-grade modules, MIT-licensed.
The loop
Pull, hack, check, push
The CLI works the way you'd write it yourself. The live preview renders locally with the same code as production: one engine, zero drift, no “looks different in the app” surprises.
Your Design System, exploded into plain files. pull then push with no edits changes nothing, byte for byte.
The dev experience
Save the file, watch it render
better dev serves a live preview with an editable inputs panel: the same settings UI your marketers use, wired to the files in your editor.
The marketer’s inputs panel, against your local files
Exercise
settings.jsonwhile you write it: edit values in the panel, see the render change. What you ship is exactly what they get.Rendered locally by the production code
Not a lookalike, not a proxy:
better devruns the same render pipeline in-process. Works offline, no login required.Save a file, every preview reloads
Module switcher, Desktop and Mobile viewports, hidden modules marked. Deep-link a teammate straight to the module you're working on.
The Better Email Design Systems extension for VS Code starts better dev and opens the preview beside your code, with schema-aware autocomplete, inline better check diagnostics, and a module tree view.
Install from the VS Code Marketplace or Open VSX for Cursor and friends.
Release safety
Your refactor can't break 400 in-flight campaigns
better push writes to exactly one place: the Candidate channel. Going Live stays a human decision. Push stages, publish gates.
your repo
Modules, settings schemas, base. PRs, review, CI.
Candidate
Staged revision. Previewable and testable in-app. Never auto-Live.
Live
Usage guard re-runs at publish. Full provenance on every version.
Campaigns
Floating campaigns follow the latest. Pinned campaigns stay put.
The platform knows what your diff touches
Git can tell you what changed. Better tells you who it affects. Remove a module that live campaigns still use, and the push says so before anything moves:
Push is polite
A push negotiates the same editing lock as every other editor. It never clobbers a colleague's open session or a Candidate it didn't create:
In CI
Reviews with receipts
One GitHub Action covers the whole loop. On pull requests, better check validates the files and a sticky comment shows the module diff against Live. On merge to main, the design system is pushed as a Version, staged as a Candidate, and never auto-published. CI ships Versions. People publish.
better-email bot
commented on pull request #142
Design System diff vs Live Version 12
| Module | Change | Flags |
|---|---|---|
| Hero | ~ edited | content, settings |
| Testimonial | + added | — |
| Legacy banner | - removed | — |
Template Base unchanged · Module order changed
On-ramps
Keep your build
Nobody rewrites forty modules to try a new tool.
Maizzle
$ better-maizzle build && better pushKeep your Maizzle and Tailwind build. Annotate a component with a better: front-matter block and the build emits modules, validated by the same serializer push uses. Starter repo.
@better-email/maizzleReact Email
$ email build && better pushExport a settings schema next to your components. Your JSX stays the source; the build output becomes modules your marketers can use. Starter repo.
@better-email/react-emailStarting fresh
$ npm create better-emailA scaffold with the full layout, JSON Schemas wired for autocomplete, and an AGENTS.md for your coding agent. Learn from Meridian, the open starter Design System.
create-better-emailBoth worlds
Marketers never see your terminal
Flip a Design System to managed-in-code and the deal is enforced: structure lives in your repo, content stays in the cloud.
Managed in code — Modules and the Template Base are edited in your team's repository. Campaign editing is unaffected.
What marketers keep (everything)
- Building and editing campaigns, visually
- Approvals, comments, and review flows
- Localization across every market
- Pre-flight checks and client testing
- One-click export to the ESP
The in-app module editor goes read-only for everyone, so there is no two-way merge problem and no “who overwrote my change” conversation. Reversible anytime, per Design System, from settings.
Agents
Your coding agent speaks email now
Plain files, published schemas, and a fast check loop are exactly what coding agents are good at. The same push guardrails apply to them, too.
AGENTS.mdAGENTS.md in every scaffold
The file format, the check loop, and the rules of the road, written for coding agents. better ai-files install adds them to any existing repo, Claude Code skill included.
better-email-mcpMCP server
Claude Code, Cursor, or any MCP client can pull, diff, check, and stage a Candidate from inside your session. Same API as the CLI.
npx skill add better-emailInstallable agent skill
Teach your agent the module format and the release model once. It scaffolds new modules that pass check on the first try.
FAQ
Questions
Is the local preview really identical to production?
Yes. better dev renders locally with the same render code that powers the app and your exports, not a reimplementation of it. One engine, zero drift. It even works offline, with no login.
What is the file format?
Plain Liquid and JSON: a design-system.json, the Template Base as base.liquid, and one directory per module holding module.liquid, settings.json, and module.json. Every JSON file has a published JSON Schema for IDE autocomplete. pull then push with no edits changes nothing, byte for byte.
Can marketers keep working while we manage the system in code?
Yes. Campaign editing, approvals, localization, and ESP export are untouched. Only module and Template Base editing moves to your repo. The in-app module editor becomes read-only with a banner pointing at it, and the flag is per Design System and reversible anytime.
What happens if someone is editing in the app when I push?
The push negotiates the same editing lock as every other editor. If a colleague holds it, the push fails and tells you who has it. It never clobbers their session, and it never overwrites a Candidate it didn't create without explicit acknowledgment.
Does it work with Maizzle or React Email?
Yes. Adapters keep your existing build: annotate components with a settings schema, then maizzle build && better push (or the React Email equivalent) emits modules. You migrate a design system without rewriting it.
Do we have to adopt all of it at once?
No. The CLI works without changing who owns what: pull your Design System into a repo, preview and push from code, and the in-app editor stays fully editable. Flipping a Design System to managed-in-code is a separate, reversible step for when the repo should become the single source of structure.
How do I get started?
Design Systems as Code is included with Better Email. Install @better-email/cli, run better login (it signs you in through the browser), then better pull. Not on Better Email yet? Request a demo.
Best of both worlds. No compromises.
Your workflow in git. Your organization shipping from the same design system. Pull yours down now, or see it on your own modules in a 30-minute demo.
Request a demoBring your stack