A single-pass Go renderer for most of Liquid, fast enough to try before falling back to a full engine.
mist evaluates as it scans, with no parse tree and no allocations on the hot path: about 10–80× faster than liquidjs on its benchmark templates. For every template it accepts, its output matches liquidjs 10 (lenientIf: true) byte for byte. Anything it can't render exactly returns ErrUnsupported, so you render that template with your full engine instead.
Use it in front of liquidjs (or an engine that behaves like it) when you render many templates and most of them are ordinary. It isn't a complete Liquid engine on its own.
go get github.com/customerio/mistRequires Go 1.25 or newer.
out, err := mist.Render(tpl, vars, strict)
switch {
case errors.Is(err, mist.ErrUnsupported):
out, err = fullEngine.Render(tpl, vars, strict) // outside what mist renders exactly
case errors.Is(err, mist.ErrUndefined):
// strict mode, undefined variable; the full engine fails too
}vars is plain JSON-shaped data (map[string]any). mist.Append renders into a reusable buffer without allocating.
go run github.com/customerio/mist/cmd/mistcheck@latest template.liquidIt reports the first construct each template uses that mist doesn't render; -stats summarizes a whole set. See docs/mistcheck.md.
| docs/supported.md | What renders, by tag, expression and filter, and what falls back |
| docs/extending.md | Engine: custom tags and filters, chains of templates, dialects for other Liquid engines |
| docs/mistcheck.md | The template checker |
| SPEC.md | The normative grammar and semantics, and how parity is verified |
| pkg.go.dev | API reference with runnable examples |
| CONTRIBUTING.md · AGENTS.md | Working on mist, for people and coding agents |
| SECURITY.md | Reporting vulnerabilities, verifying releases |
Releases and their notes are on the releases page. Report bugs, including any output that differs from liquidjs, in issues.