luazig: Lua in Zig
luazig is my reimplementation of Lua 5.5.0 in Zig.
The goal is drop-in behavioral compatibility with PUC Lua, not a new Lua-like language. The reference implementation stays close at hand: the same programs are run by both engines, then their exit codes and output are compared.
Current status
The project is still pre-release and focused on correctness. At the time of writing it has reached:
- 30 of 31 upstream
testes/*.luafiles passing with exit-code parity. - No remaining output differences in the differential test lane.
- 49 of 49 smoke tests passing.
The remaining upstream case, big.lua, expects the coroutine.wrap harness normally supplied by Lua’s all.lua test runner.
How it works
The active backend is a bytecode virtual machine. Source code passes through a lexer and parser, is compiled into Lua bytecode, then runs on a shared-stack VM. The project also includes standard-library support, binary chunk serialization, a Zig-facing embedding API, and a C ABI for loading extensions.
Testing is deliberately differential: upstream Lua tests, focused smoke tests, API regressions, and performance workloads all run against both PUC Lua and luazig. This makes compatibility visible and measurable instead of relying on a collection of hand-picked demos.
Why Zig
Zig offers explicit memory management and low-level control while keeping the implementation readable. Reimplementing Lua this way is also a practical route into the internals of an embeddable language: parsing, bytecode generation, VM semantics, garbage collection, the standard library, and API design.
Performance work follows correctness. The current benchmark geomean is about 2.76x slower than PUC Lua; the repository tracks the measurements and optimization history openly.
Repository: github.com/Rlambda/luazig