raylib-zig: raylib-zig (raylib 6.2 ported to Zig, checked against C, running in the browser)
raylib-zig is a port of raylib 6.2 from C to Zig. It isn’t one of the existing Zig bindings. raylib’s own modules (core, shapes, textures, text, models, audio, rlgl, raymath, rcamera, rgestures) are rewritten in Zig. The bundled third-party C (stb, miniaudio, GLFW, cgltf and so on) is still linked as C.
Try it in the browser: raylib-zig
NOTE: Its WIP as all examples are being tested and updated to website.
Port: GitHub - algorisys-oss/raylib-zig-port: An AI port of the excellent raylib to zig (as a learning experiment of using Agentic AI coding) · GitHub · Site: GitHub - algorisys-oss/raylib-zig-web: Documentation site for raylib-zig: every example runs in the browser from the Zig port, verified against C raylib (unofficial) · GitHub
Before you ask why waste token, let me clarify. This is built for me and my team as a learning exercise for zig. My aim is not to show of this as a great graphics library for zig, atleast not at this point in time. Eventually, after more testing and fixes, it might become as I add real uses cases.
Some background: I also made ziglang.in, a Zig guide where every snippet is compiled and run against Zig master in CI, nightly. raylib-zig’s site lives under it.
I plan to keep this both and more zig website maintained till zig reaches ver 1.0.
May be after that also this might be useful as all examples will still be working as that is the goal of this entire project.
Design decisions → The below is LLM summary based on my inputs. I have put it down here if anyone is curious.
- Same C ABI, plus an idiomatic Zig API. All 619 functions in
raylib.hare exported from Zig objects, so an existing C raylib program links against the port unchanged. On top of that there’s a Zig API generated from the headers and kept in raylib’s style:rl.drawText(...), real enums, slices, error unions. - The examples are the test suite. raylib has no test suite, so each of its examples runs for 240 frames with the clock frozen and the random seed fixed, once on C raylib and once on the Zig port. The final frames must match byte for byte. On Linux x86-64 (GLFW, OpenGL 3.3), all 217 deterministic examples match, in Debug and ReleaseFast. The other 10 are listed with reasons; most are audio examples where even C doesn’t give the same frame twice. raymath, rcamera, rgestures and audio decoding are also compared bit for bit.
- Floating point had to match C exactly. clang fuses
a*b + cinto one instruction by default, and Zig never does, so all C in the build is compiled with-ffp-contract=off. A rotated 3D text example shifted by a sub-pixel until that was found.
Something interesting: the web target
raylib’s web backend and its WebGL 2 path are now ported too. The platform backend and the GL binding are picked at comptime from the target OS. raylib’s web backend uses inline JavaScript (EM_ASM), which Zig can’t emit, so those snippets live in an Emscripten JS library that the Zig code calls through extern fn. The same byte-for-byte comparison runs in headless Chrome; so far it covers only a few examples.
Two port bugs showed up only on wasm32:
time()declared as returningc_long. That equalstime_ton x86-64 but not on wasm32, and the link produced invalid wasm. The per-OS types now come fromstd.c.- C variadic arguments forwarded as
&ap. C’sva_listis an array on x86-64 (so it decays to a pointer) but a plain pointer on wasm32. On wasm32,vprintfgot the address of the list: Debug printed garbage, and ReleaseFast crashed the browser tab.
raylib is the work of Ramon Santamaria (@raysan5) and its contributors. This port is unofficial and keeps raylib’s zlib/libpng license.
Supported Zig versions
Zig master: built and checked on 0.18.0-dev.246. It tracks master, so older releases won’t build it. Suggested tag: zig-master (or whichever master/0.18 tag Ziggit uses).
AI / LLM usage disclosure
Tags: llm
Most of the code was written by an AI coding agent (Claude Code), working under rules and a design I set and then checked.
My part: I chose the architecture (port module by module, keep the C ABI at every boundary, use the examples as the oracle, a separate idiomatic Zig API), wrote the project rules and quality bar the agent follows, made the design decisions, and reviewed the results. The agent’s work is only accepted when the byte-for-byte comparisons against C raylib pass. Those checks are why I trust the result, rather than trusting the AI.
The dependencies (raylib’s C, stb, miniaudio, GLFW) are upstream projects, not AI-written.