Latest: v0.0.35, 11 November 2026

A patch release with speed work, out the same day as v0.0.34's interpreter release. The experimental optimizing tier compiles a function that starts with a loop, with a fix contributed for issue #93; compiled loops that read and write globals are faster again; and frameless calls and object allocation do less work. The benchmarks page still shows v0.0.31's profile-guided capture; the release notes give v0.0.35's measurements against v0.0.34 and Node 24.

  • New, from a contributor: the optimizing tier (ZIPP_OPT=1, off by default) compiles a function whose first instruction is a loop's head, through a preheader that merges the values the function is entered with and the values the loop carries back (codeandsolder's fix for #93; v0.0.34 had Tier O decline such functions). Under ZIPP_OPT=1, an integer loop at a function's start runs in 62 ms where the decline took 69, a floating-point one in 16 against 21, and a function that runs its loop once per call 2.4 times faster.
  • Faster, compiled code: the blocks that hand an operation back to the interpreter come after a function's code instead of behind each operation, so the success path falls through; v0.0.34 had given one to every compiled global access. With the JIT, class-prototype-hot takes 0.81× v0.0.34's time, sparse-array 0.85× and nbody 0.86×.
  • Faster, the interpreter: a small function run without a frame reads its captured variables through one fetch of its closure's list, and a number written to one skips the write barrier; allocating no longer reserves and probes 32 KB of stack in every function that makes an object. Interpreted, upval_rw takes 0.88× v0.0.34's time and is now ahead of node --jitless.
  • Over 90 benchmark programs v0.0.35 takes 0.984× v0.0.34's time with the JIT and 0.997× interpreted; it is ahead of Node 24 on 72 of the 89 programs Node runs, and of node --jitless on 71 interpreted.
  • v0.0.34 (11 November, not described here before): on the x86-64 command lines, interpreted loops and the calls they make run through a second, leaner form of the interpreter, whose instructions are small functions that jump from one to the next. Interpreted, it takes 0.83× v0.0.33's time over the 90 programs and is ahead of node --jitless on 71 of 89; a global deleted or given an accessor by code a running compiled loop called is no longer read as the plain variable it was; and Tier O no longer runs forever on a function that starts with a loop.
  • WebAssembly modules: the six of v0.0.33 and v0.0.34, the same size. As published, the JavaScript engine is 1.25 MB on the wire, ZIPP Lite 0.78 MB, the TypeScript engine 1.32 MB, Python without torch 1.65 MB and the complete engine 2.02 MB; the torch package 0.40 MB. Loader zipp.mjs 1.5.0, unchanged, and host SDK 1.4.0.
v0.0.35 assets
AssetBytesContents
zipp-0.0.35-windows-x86_64-portable.exe26,045,952Native CLI for Windows x86-64, complete: JavaScript and TypeScript with the x86-64 JIT, Node programs, WebAssembly on Wasmtime, Python with its JIT tier, torch and the native GPU path; runs from anywhere
zipp-0.0.35-windows-x86_64-installer.msi8,302,592The same CLI as a per-user install into %LOCALAPPDATA%\Programs\ZIPP that adds zipp to the user's PATH; no administrator rights
zipp-0.0.35-linux-x86_6431,412,456Native CLI for Linux x86-64, same contents; glibc 2.35 or later, chmod +x after downloading
zipp-0.0.35-linux-arm6424,727,960Native CLI for 64-bit Arm Linux
zipp-0.0.35-linux-armv720,374,308Native CLI for 32-bit Arm Linux with hard float, interpreter only, WebAssembly on wasmi
zipp-0.0.35-javascript.wasm4,855,175JavaScript engine, with Intl and Temporal, for pages, Workers, Node, Deno and Bun
zipp-0.0.35-javascript-lite.wasm2,832,722ZIPP Lite: the JavaScript core without Intl and Temporal, built for size
zipp-0.0.35-javascript-typescript.wasm5,192,500The JavaScript engine with TypeScript and TSX; zipp.mjs 1.5.0 runs a TypeScript program in it
zipp-0.0.35-javascript-python.wasm8,617,556JavaScript + Python with torch built in
zipp-0.0.35-javascript-python-base.wasm6,580,459JavaScript + Python without torch
zipp-0.0.35-torch-package.wasm2,163,109The torch package, added to the -javascript-python-base engine when a program needs it
zipp-0.0.35-javascript.wasm.br1,253,800The JavaScript engine compressed with Brotli: the same module at about a quarter of the size. Serve it with Content-Encoding: br and Content-Type: application/wasm and the browser decodes it, or let zipp.mjs 1.5.0 load it
zipp-0.0.35-javascript-lite.wasm.br778,494ZIPP Lite, Brotli-compressed
zipp-0.0.35-javascript-typescript.wasm.br1,324,793The TypeScript engine, Brotli-compressed
zipp-0.0.35-javascript-python.wasm.br2,020,289JavaScript + Python with torch, Brotli-compressed
zipp-0.0.35-javascript-python-base.wasm.br1,645,492JavaScript + Python without torch, Brotli-compressed
zipp-0.0.35-torch-package.wasm.br403,192The torch package, Brotli-compressed
zipp-0.0.35-wasm-embed-kit.zip219,173The loader zipp.mjs 1.5.0, the one file a page needs beside an engine, with its TypeScript types, the engine API types, the host SDK, the GPU lab, the docs and examples. It loads a .wasm.br too: decoded by the server, decompressed by the loader where the runtime can (Node, Firefox), or by falling back to the plain .wasm beside it
SHA256SUMS1,803Checksums for all 18 files above

Release notes and downloads on GitHub · docs/releases/0.0.35.md · v0.0.34 notes · v0.0.33 notes · v0.0.32 notes · v0.0.30 notes · v0.0.29 notes · v0.0.28 notes · v0.0.27 notes · v0.0.26 notes · v0.0.25 notes · v0.0.24 notes · v0.0.23 notes

Install

From a release download
# Windows: the portable .exe runs from wherever you saved it
.\zipp-0.0.35-windows-x86_64-portable.exe js app.js
# or install zipp-0.0.35-windows-x86_64-installer.msi, which adds zipp to
# your PATH without administrator rights
zipp js app.js

# Linux x86-64 (zipp-0.0.35-linux-arm64 or -linux-armv7 on Arm), glibc 2.35+
curl -fL -o zipp https://github.com/f2i-com/zipp.org/releases/download/v0.0.35/zipp-0.0.35-linux-x86_64
chmod +x zipp
./zipp js app.js

# WebAssembly, for a web page: the loader zipp.mjs from the embed kit, and one
# engine (or its .wasm.br: the same engine, about a quarter of the size)
curl -fLO https://github.com/f2i-com/zipp.org/releases/download/v0.0.35/zipp-0.0.35-wasm-embed-kit.zip
unzip -j zipp-0.0.35-wasm-embed-kit.zip zipp-0.0.35-wasm-embed-kit/zipp.mjs
curl -fLO https://github.com/f2i-com/zipp.org/releases/download/v0.0.35/zipp-0.0.35-javascript.wasm

# From source, any platform with Rust 1.92
git clone https://github.com/f2i-com/zipp.org && cd zipp.org
cargo build --locked --release
./target/release/zipp --version --json

Zipp is not on crates.io or npm yet. The WebAssembly engines and the embed kit are meant to be served by your own host, over HTTP: a page needs zipp.mjs from the kit beside whichever .wasm it loads. Serve a .wasm.br with Content-Encoding: br and Content-Type: application/wasm and the browser decodes it; zipp.mjs 1.2.0 also loads one itself, decompressing it where the runtime can or falling back to the plain .wasm beside it. The embed section of the home page has a starter project, and the WebAssembly page explains the loader, its sandboxes and the Worker model.

Up to v0.0.25 the downloads were archives: zipp-<v>-x86_64-pc-windows-msvc.zip for Windows, zipp-<v>-x86_64-unknown-linux-gnu.tar.gz for Linux, which unpacks to a folder holding zipp, and zipp-wasm-<v>-web.zip and its siblings for the WebAssembly engines. From v0.0.26 they are the plain files above, and the WebAssembly page describes the engine files and the embed kit.

What a release has to pass

Pushing a vX.Y.Z tag runs the release workflow. It refuses to publish unless the tag object matches the checkout; the root Cargo.toml, the WebAssembly crate and the landing page all carry the same version; and the reusable CI, the full security workflow (including the pinned Test262 corpus), the native build and the WebAssembly build all pass at that exact commit. A green main at some other revision is not a release gate. The job is retry-safe: it re-downloads existing assets, verifies SHA256SUMS, and checks that BUILD-INFO.json is not dirty and names the right commit before deciding to do nothing. A dispatched re-run may skip the two longest gate jobs - the native workspace suite and Test262 - only when the identical tree has been through them elsewhere; v0.0.19 was published that way, with both run locally on the tagged commit (308 test binaries, 2,453 tests; 95,680 of 95,680 corrected-core executions) and every other job in the workflow, and so was v0.0.20, whose JavaScript engine source had not changed since v0.0.19 passed them. From v0.0.21 the workflow also builds the torch package with the two engines it pairs with, and refuses to publish unless python plus the package prints exactly what all prints over the torch suites. From v0.0.22 it also builds ZIPP Lite. v0.0.24's first run lost four gate jobs to GitHub runner shutdowns, and those jobs were re-run at the same commit before it published. v0.0.27 was dispatched the same way: its tagged commit changes only versions and release notes from 05d2bd9b, where the full security workflow, the native workspace suite and Test262 on 64-bit and 32-bit builds included, had passed. So was v0.0.28, after the CI and the full security workflow had passed on its tagged commit itself. So was v0.0.29: the full security workflow on its prep commit, 8cd844fd, had failed one test, a heap-ceiling regression, whose fix and the heap and limit tests around it were run before 58c92a59 was tagged, and Test262 then passed on the published Windows binary, with its JIT and without. So was v0.0.30: the full security workflow passed at ef3bea8a once its benchmark lane stopped running the hour-long comparison of the profile-guided training corpus, which tools/pgo.sh still runs before every profile-guided build, and the tagged commit, fd6b48a5, changes only a landing test from it; and Test262 then passed on the published Windows binary, with its JIT and without. So was v0.0.31: CI and the full security workflow passed at 051577de after its dependency audit had refused Wasmtime 44.0.3 for eight advisories, and the release run's own builds then found two faults no gate builds for, an extra parenthesis in the release smoke test's WebAssembly program and dead code on 32-bit Arm, fixed in 1a0098b0 and 85fb9d3e, which change no x86-64 code; the tagged commit, fcfb1934, changes only the release notes from them. The release's arm64 build ran the pinned Test262 corpus in full, and it then passed on the published Windows and Linux x86-64 binaries, with their JIT and without. So was v0.0.32, after its gate refused the first commit tagged: the first release run, at 6112d701, failed the pinned Test262 corpus on one test, strict and sloppy, a class's static initializer whose arrow reads the class's name through eval, which that release's own fix for arrows in class methods (08f34f83) had broken. The tag was moved to the fix, e312cf40, before anything was published, and the release run's CI and full security workflow, the corpus included, then passed at that commit, with the arm64 build running it in full. v0.0.33's gate caught a crash before the tag: the release build's dry run stopped on its arm64 build, where one Test262 test, staging/sm/extensions/recursion.js, overflowed the native stack instead of throwing a RangeError. The fix (78097701) bounds native re-entry by the stack the command line declares; CI, the full security workflow and the dry run then passed at that commit, and the release was tagged on it with only versions and notes changed (cc75c2a3). v0.0.34 was published twice: the build of 10 November was withdrawn within the hour and replaced by one with the optimizing tier's fix for #93 and without the 22% slowdown on a request loop that the first build's notes had reported. For v0.0.35 the release build's dry run, CI and the full security workflow, the corpus included, passed at cd86ccdb, and the release was tagged on it with only versions and notes changed (384cb93a).

All releases

Tags, dates and the headline from each tag annotation
VersionDateHeadline
v0.0.352026-11-11Tier O compiles a function that starts with a loop (a contributed fix for #93), compiled bail-outs moved out of the way, and frameless calls and allocation that do less work
v0.0.342026-11-11A leaner second interpreter for loops and their calls on x86-64 (0.83× v0.0.33's time interpreted), compiled code that sees a global changed under it, and Tier O no longer looping forever on a function that starts with a loop
v0.0.332026-11-07Smaller WebAssembly engines without Node's layer; faster objects, calls, try, classes, arrays, strings and regular expressions; an experimental optimizing tier; and four fixes, a compiled loop that could not collect garbage among them
v0.0.322026-10-29WebAssembly on Wasmtime in large programs, externref values let go, an app's state read in one JSON text, faster Reflect.set and Object.defineProperty, and an arrow in a class method that sees the method's locals
v0.0.312026-10-29TypeScript and TSX run directly, Node programs, WebAssembly on Wasmtime or wasmi held to the sandbox's limits, class methods inlined by the JIT, and a sixth WebAssembly module with TypeScript
v0.0.302026-10-27Function bodies compiled at their first call, half-size instructions and a half-size syntax tree, faster bundled applications on the interpreter; a stricter sandbox loader; Unicode 18 normalization and the latest Test262
v0.0.292026-10-23Embedded scripts' own positions, bounded host requests and a checked redirect; one shared copy of a script's source and a zipp js code cache; a heap ceiling that collects before it convicts
v0.0.282026-10-21Eleven reported issues fixed; import.meta.url, unhandled-rejection reports, V8-format Error.stack and run_script; Babel and TypeScript run more than twice as fast
v0.0.272026-10-18Seven reported embedding issues fixed; regular expressions compile in bounded time; a Brotli .wasm.br beside every WebAssembly engine
v0.0.262026-10-18Plain downloads, Linux arm64 and armv7 included; one-file WebAssembly engines in a default-deny sandbox; the latest Test262, unmodified, on 64-bit and 32-bit builds
v0.0.252026-10-15Ten reported embedding issues fixed; the safe-sandbox interpreter at 0.84× Bellard's QuickJS; script globals in their slots; evaluated code freed
v0.0.242026-10-14Eight reported issues fixed; more of JavaScript compiled; Python at 1.09× CPython; torch at 4.2× PyTorch; smaller modules
v0.0.232026-10-12Memory grown in place collected; builtins call compiled code directly; Python at 1.30× CPython; smaller modules
v0.0.222026-10-10ZIPP Lite; an application bridge for hosts; member calls fast again under the strict call order; modules 11% to 15% smaller
v0.0.212026-09-25Python at about 1.75× CPython with a JIT tier; the torch layer checked against PyTorch 2.11; torch as a WebAssembly package; native GPU through wgpu
v0.0.202026-09-18Quantized Q4_K and Q6_K weights on the GPU path, matmul_fixed, reproducible Rust kernels, and Hugging Face modelling files running unmodified
v0.0.192026-09-16Resident GPU training sessions, torch.compile prepare, native version-2 kernels; 324 reviewed defects fixed
v0.0.182026-09-14Python playground, Torch GPU support and conformance updates; first WebAssembly archive with Python
v0.0.172026-09-12Audited engine hardening: VM rooting, coercion, TypedArray, parser, GC and metadata; preserves the exact 95,939 / 95,942 Test262 result on the previous corpus
v0.0.162026-09-12The two audits of 11 September: 24 engineering tickets and 14 close-audit tickets
v0.0.152026-09-07The audit response: spec-order method calls by default, accel spec grammar, transactional host.call, zippProfile(), CI gate
v0.0.142026-09-06The accel bridge
v0.0.132026-09-02A host-sized instruction budget
v0.0.122026-09-02Inline stores into pinned young dense arrays; x | 0 fused into the wrapping add; 21 of 30 benchmark rows faster than Node
v0.0.112026-09-02Register classes keep tokenizer loops on the INT tier (parse-large-js 1.24× to 0.88× Node); a forced-JIT segfault on user-overridden Math.random fixed
v0.0.102026-09-01Hardened limits sized for applications rather than snippets: 1 GB instance ceiling, 512 MB heap budget
v0.0.92026-09-01Collections scheduled on bytes, not only allocation count, after an emulator died ninety seconds into a game
v0.0.82026-09-01renewInstructionBudget and setFingerprintSeed; the 50M lifetime budget had been a fuse on every long-running embedder
v0.0.72026-09-01ArrayBuffer ceiling raised from 1 MB to 32 MiB
v0.0.62026-09-01Runtime optimization, exact WebAssembly benchmarks, QuickJS-NG comparison source
v0.0.52026-08-31Benchmark evidence publication
v0.0.42026-08-31getGlobalsFingerprint: a content digest so a mutation through a reference cannot be missed; per-tick host sync 9.6 ms to 2.1 ms
v0.0.32026-08-31Interpreter-only WASM stops an O(heap) walk; JSON.stringify ×4000 from 919 ms to 8.5 ms; wasm-opt dropped after measurement
v0.0.22026-08-31The boundary tax: the host boundary stopped walking the whole heap per re-entry; parser sandbox limits raised
v0.0.12026-08-30First native and WebAssembly distribution

Release notes for v0.0.1 through v0.0.17 live in the annotated tag messages; v0.0.18 is the first with a notes file in docs/releases/, and from v0.0.20 that file is the GitHub release body verbatim. The engineering journal tells the story between the tags.