liquidz
A Liquid template engine written in Zig.
Why
- 💎 Ruby-only limitation: Shopify maintains Liquid only in Ruby since they can assume a Ruby runtime on their servers and developers' machines. The rest of us aren't so lucky.
- 🎯 Universal reach: A systems language like Zig lets us target every platform: standalone binaries, WebAssembly, and libraries that any runtime can include via foreign function interfaces.
- 🔧 One implementation to rule them all: Instead of maintaining separate Liquid parsers for each platform or language, we maintain one battle-tested implementation and build bindings for the rest.
Usage
# Build
zig build
# Render template
./zig-out/bin/liquidz template.liquid '{"name": "World"}'Language Bindings
Node.js
npm install liquidzimport { render } from 'liquidz';
console.log(render('Hello, {{ name }}!', { name: 'World' }));Browser
import { init, render } from 'https://unpkg.com/liquidz/browser.mjs';
await init();
console.log(render('Hello, {{ name }}!', { name: 'World' }));Bun
bun add liquidzimport { render } from 'liquidz';
console.log(render('Hello, {{ name }}!', { name: 'World' }));Deno
deno add npm:liquidzimport { render } from 'liquidz';
console.log(render('Hello, {{ name }}!', { name: 'World' }));Ruby
gem install liquidzrequire 'liquidz_ext'
puts Liquidz.render("Hello, {{ name }}!", { name: "World" })Elixir
# mix.exs
{:liquidz, "~> 0.5"}Liquidz.render!("Hello, {{ name }}!", %{name: "World"})Python
pip install liquidzfrom liquidz import render
print(render("Hello, {{ name }}!", {"name": "World"}))Testing
# Unit tests
zig build test
# Golden Liquid tests
cd test && ruby run_golden_tests.rb
# Liquid Spec tests
cd test && ruby run_liquid_spec_tests.rbBenchmarks
Liquidz is significantly faster than Ruby Liquid. Benchmarks are measured using hyperfine with 1000 render iterations per run.
Comprehensive Template
A comprehensive template that exercises all major Liquid tags and filters against realistic e-commerce data:
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
| Liquidz (Zig) | 252.5 ± 81.0 | 204.0 | 529.8 | 1.00 |
| Ruby Liquid | 844.3 ± 52.7 | 797.3 | 978.8 | 3.34 ± 1.09 |
Liquidz is ~3.3x faster than Ruby Liquid.
Shopify Dawn Theme
We also benchmark against real-world templates from Shopify's Dawn theme. Out of 92 templates, 28 work with Liquidz. The remaining templates use Shopify-specific extensions like {% form %}, {% schema %}, and Ruby-style method calls (product.gift_card?) that are not part of standard Liquid.
| Template | Liquidz [ms] | Ruby [ms] | Speedup |
|---|---|---|---|
| card-collection.liquid | 12.0 ± 1.1 | 186.7 ± 106.1 | 15.6x |
| facets.liquid | 20.1 ± 1.1 | 171.7 ± 35.6 | 8.5x |
| price.liquid | 37.4 ± 71.1 | 171.5 ± 40.9 | 4.6x |
On Dawn templates, Liquidz is 5-15x faster than Ruby Liquid.
Running Benchmarks
# Quick benchmark (single template)
./benchmark/run.sh benchmark/templates/comprehensive.liquid 1000
# With hyperfine for statistical rigor
./benchmark/run.sh benchmark/templates/comprehensive.liquid 1000 --hyperfine
# Benchmark all Dawn theme templates
./benchmark/run.shThe benchmark infrastructure is in the benchmark/ directory. It includes:
-
bench.zig- Zig benchmark runner -
ruby_bench.rb- Ruby benchmark runner for comparison -
run.sh- Wrapper script for running comparisons -
templates/comprehensive.liquid- Comprehensive template using all features -
themes/dawn/- Shopify Dawn theme templates -
shopify_mock_data.json- Realistic e-commerce data
License
MIT