Skip to content
zigccPublic

About

Try Zig in your browser

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Zigtools Playground

Run and explore Zig in your browser, with compiler and LSP support built in.

Multi-version compilers

Site: https://play.ziglang.cc/

Path Meaning
/ Configurable default (versions.json → default, currently 0.16.0)
/0.16.0/ Current stable pin (same binaries as /)
/0.15.2/ Older pin (binaries from Release; rebuild only when forced/missing)

Shared UI under /assets/. Per-version compilers:

/compilers/<id>/zig.<hash>.wasm
/compilers/<id>/zls.<hash>.wasm
/compilers/<id>/libcompiler_rt.<hash>.a
/compilers/<id>/zig.<hash>.tar.gz
/compilers/<id>/meta.json

Compiler asset filenames carry a content hash so the CDN can cache them immutably; meta.json maps logical names → hashed filenames (the one fixed-name file). Large binaries are never committed.

Design: docs/superpowers/specs/2026-07-26-multi-version-compilers-design.md

Consume the compilers from another site

This site also ships a small ESM loader — https://play.ziglang.cc/zp-loader.js — so other projects can fetch these compilers without re-implementing the hash-filename / meta.json / Cache-Storage logic. Import it directly (works in Web Workers):

import {
  fetchCompilerFile,
  compileCompilerWasm,
  getZigLibDir,
  listVersions,
} from "https://play.ziglang.cc/zp-loader.js";

Always pass logical names — the loader resolves the content-hash filename from each version's meta.json:

Logical name What
zig.wasm the compiler
zls.wasm the language server
libcompiler_rt.a compiler-rt archive
zig.tar.gz the standard-library tree

Examples

// 1) List the published versions (cache: no-store).
const { default: def, versions } = await listVersions();
// → { default: "0.16.0", versions: [{id:"0.16.0",label:"0.16.0"}, …] }

// 2) Compile zig.wasm + load the std-lib tree for a version.
const zigModule = await compileCompilerWasm("0.16.0", "zig.wasm");
const stdLibDir = await getZigLibDir("0.16.0"); // WASI Directory from zig.tar.gz

// 3) Fetch any logical file as bytes (e.g. compiler-rt).
const crt = await fetchCompilerFile("0.16.0", "libcompiler_rt.a");

Notes:

  • Cross-origin fetch is permitted (the host serves permissive CORS). Large assets are cached by the loader via Cache Storage keyed by the hashed URL, so a hit is always the right bytes — offline-friendly after first load.
  • meta.json is always revalidated (cache: "no-store"), so new builds are visible without a cache-bust.
  • Self-hosting: call configure({ origin: "https://your.host" }) once before any other call to point at your own /compilers/<id>/… tree. The default origin is the loader's own host (https://play.ziglang.cc).

How builds are chosen

versions.json is the build orchestrator, not only the UI list:

Field Role
default / resolves to this id
versions[].id / label URL path + dropdown
versions[].zig.path / zig.git Source for that id (local path preferred; else clone git.ref)
versions[].zig.patch Optional repo-relative patch applied after clone (CI)
versions[].zls.url / hash Paired ZLS package
versions[].zigVersionString Passed as -Dzig-version-string

Source trees (do not use GitHub ziglang/zig master — it is a Codeberg stub):

id build git hostZig notes
0.16.0 in-tree codeberg.org/ziglang/zig@0.16.0 0.16.0 zig.wasm in-tree + ZLS 0.16.0 (Zig is not a package from 0.16)
0.15.2 playground github.com/ziglang/zig@0.15.2 0.15.2 full zig+zls via repo build.zig

Local overrides: ../zig-0.16.0, ../zig-wasm (0.15.2). Hosts via zvm i 0.16.0.

(A master tracking build existed until 2026-08; re-enable by restoring the versions.json entry — the toolchain in scripts/ still supports schedule/hostZig: master in-tree builds.)

npm run compilers:plan          # dry-run: who would build
npm run compilers:stable        # all pinned versions
npm run compilers -- --only 0.16.0

Installation

Requires host Zig matching each pin (0.16.0 for the default; 0.15.2 if building that pin). Install with zvm i 0.16.0.

npm run compilers:stable    # reads versions.json → zig build → public/compilers/<id>
npm install
npm run dev

Open / (→ 0.16.0) or /0.16.0/ / /0.15.2/. Toolbar dropdown does full-page navigation.

Production dist

npm run compilers:stable    # or :scheduled / --select all
npm run build               # vite + assemble-dist
npm run preview

CI / Deployment

Live deploys run on the gx VPS webhook (branch master): a push to master fires the GitHub webhook → the shared receiver on gx (adnanh/webhook) → scripts/server/deploy.sh (fetch → compilers from the compilers Release → npm ci + vite build → rsync to the web root, publish in ~1 min). Setup and operations: scripts/server/README.md.

Workflow Role
Build Compilers (build-compilers.yml) Manual workflow (workflow_dispatch). Compiles selected or all Zig / ZLS WebAssembly compiler targets from source and creates/updates the compilers Release on this repository.
Deploy to GitHub Pages (deploy.yml) Dormant: it triggers on main only (live deploys come from master via the gx webhook) and GitHub Pages is not enabled. If adopted later, it reuses the compilers Release the same way the gx deploy does.

Workflow strategy: Build compilers once → publish to GitHub Release → Pages deployment reuses release binaries.

Optional repository variables:

  • COMPILERS_RELEASE: Release tag containing compiler archives (defaults to compilers).
  • VITE_BASE: Base path for Vite assets (automatically configured by actions/configure-pages, e.g. /play/).

Enjoy!

About

Try Zig in your browser

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages