Project

liquidz

0.0
A long-lived project that still receives updates
A fast, drop-in replacement for the Liquid template engine, compiled from Zig to native code for maximum performance.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

>= 0
 Project Readme

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 liquidz
import { 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 liquidz
import { render } from 'liquidz';
console.log(render('Hello, {{ name }}!', { name: 'World' }));

Deno

deno add npm:liquidz
import { render } from 'liquidz';
console.log(render('Hello, {{ name }}!', { name: 'World' }));

Ruby

gem install liquidz
require 'liquidz_ext'
puts Liquidz.render("Hello, {{ name }}!", { name: "World" })

Elixir

# mix.exs
{:liquidz, "~> 0.5"}
Liquidz.render!("Hello, {{ name }}!", %{name: "World"})

Python

pip install liquidz
from 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.rb

Benchmarks

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.sh

The 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