Zinc developer guide

A task-oriented guide to building, shipping and hardening apps with Zinc — the compiler from a strict TypeScript subset to native C++17 (no JavaScript engine on the device). For the project overview, targets and module list, see the top-level README; for what is and isn’t implemented, reports/STATUS.md.

Every command here is copy-pasteable and every code sample was compiled (and run where it makes sense). Longer samples live under samples/ and build with zinc run docs/guide/samples/<name>.

Set up the zinc alias once (from the repo root):

pnpm install
alias zinc="node $PWD/compiler/bin/zinc.mjs"
zinc doctor        # checks cmake, a C++17 compiler, SDL3, docker, emscripten

Contents

  1. Getting started — install, zinc init, project layout, the zinc.json reference, targets & profiles, zinc run / dev / help.
  2. The language — the supported TypeScript subset, what is rejected and why (Z diagnostics), numbers & profiles, the memory model (RC, pools, arenas, weak), errors, async, Dyn/gradual vs strict, zinc infer.
  3. UI apps — JSX with view/text/image/scroll, Solid vs React, classes/CSS/breakpoints, scrolling & VirtualList, animations, fonts/assets/images, windows (zoom/resize/fullscreen/kiosk), HiDPI, per-target constraints.
  4. Headless services — a daemon/CLI: HTTP server, MQTT/OSC, telemetry, timers, logging, shutdown, running as a systemd service, restart policy, resource budgets, ESP32 firmware. Worked example: examples/service/sensor-hub.
  5. Plugins — pure-Zinc module plugins, native plugins (spec + C++ per target + sim), UI component plugins, display driver plugins, plugin.json reference, options, packages/IDF components, testing and sharing.
  6. Testing — the sim oracle, zinc test, conformance-style tests for your own app, golden outputs, --debug ASan/leaks, determinism (virtual clock, record/replay), captures (ZINC_SHOT, zinc capture), visual regression (zinc test --pixels), dev-mode red box/inspector, benchmarks.
  7. Distribution — from zinc new game-2d to an itch.io page and a download page, worked through and run by a test; then zinc pack, fuse, export per target, signing and notarization, .dmg and .deb, SBOM, zinc publish (itch.io, a download page, signed updates), zinc update-app, mirrors.
  8. Security — threat model per deployment, memory-safety guarantees and limits, the permission keys of zinc.json and what each host module checks, network exposure defaults, systemd units, build flags, secrets, supply chain and plugin distribution, fuzzing, and what a native build hides (and does not).
  9. Web platform APIs — the WinterTC minimum common Web API as globals: fetch / Request / Response / Headers, URL, TextEncoder / TextDecoder, events, AbortController, Blob / FormData, crypto, WebAssembly; deviations and WPT results.
  10. Lint and migrate — zinc lint: what cannot work or weighs too much on each target (requires, plugins, UI tiers, screen, asset budgets), the matrix of --all-targets; zinc migrate: the codemods that come with a language or API change.
  11. Bundling for QuickJS — --engine quickjs runs TS and TSX, zinc bundle makes one optimised JavaScript file (tree shaking, defines, minify, source map, bytecode) with the pinned esbuild, zinc check --engine quickjs.
  12. JavaScript engines — one program on QuickJS, JavaScriptCore, V8 or Hermes (--engine, "engine" in zinc.json), all bound through Node-API; engine packs downloaded and checked on first use, which one to pick, --inspect, bytecode at zinc build.
  13. npm packages and the web — the web target: zinc add npm:<pkg> and zinc install call your package manager (npm, pnpm, yarn, bun), zinc dev --target web pre-bundles packages like Vite, @zinc/vite builds a Zinc app with Vite; the libraries run.

The one-minute tour

zinc init myapp --template game      # or cli | server | iot | remarkable
cd myapp
zinc run                             # native build + run (SDL3 window or headless)
zinc run --target sim                # the same program on Node (the oracle)
zinc dev                             # hot reload on save, red box on crash, UI inspector on :9229
zinc test                            # conformance: every target prints the same bytes as sim
zinc export --target macos           # dist/<name>-<target>: one self-contained executable + scripts

Edit this page on GitHub ↗