Skip to content

ZIPP v0.0.22

Choose a tag to compare

@github-actions github-actions released this 10 Oct 10:11

ZIPP 0.0.22

Smaller and faster WebAssembly engines, an application bridge for hosts, a
faster native CLI on member calls, and ZIPP Lite, a size-first JavaScript-only
engine.
The browser modules are 11% to 15% smaller than 0.0.21's and their
interpreter runs the benchmark corpus in roughly four fifths of the time it
took two passes ago; four workloads that were quadratic in a string's length
there are linear.

Downloads

  • zipp-0.0.22-x86_64-pc-windows-msvc.zip: native CLI for Windows, complete: JavaScript, Python, torch and native GPU.
  • zipp-0.0.22-x86_64-unknown-linux-gnu.tar.gz: the same native CLI for Linux.
  • zipp-wasm-0.0.22-web.zip: JavaScript-only browser engine, TypeScript bindings and Worker host SDK.
  • zipp-wasm-0.0.22-web-lite.zip: ZIPP Lite, the JavaScript core without Intl and Temporal, built for size, with the same bindings and host SDK. Added on 10 October, after the other assets, from the same tagged commit.
  • zipp-wasm-0.0.22-web-python-base.zip: JavaScript + Python without torch; add torch from web-torch when a page needs it.
  • zipp-wasm-0.0.22-web-python.zip: JavaScript + Python complete, torch built in, with the browser GPU adapter and CPU WASM kernels.
  • zipp-wasm-0.0.22-web-torch.zip: the torch package, zipp_torch.wasm and its zipp_torch.js loader, added to web-python-base through addPythonPackage.
  • SHA256SUMS for every asset.

Every WASM archive includes BUILD-INFO.txt, PROFILE.json and SHA256SUMS.
Publishing requires CI and the full security workflow at the exact tagged commit.

The local-model plugins (crates/zipp-wasm/model-plugins/) remain an
experimental, source-only package.

WebAssembly size

Module sizes on a Windows build of this release's source, raw and Brotli-11,
beside 0.0.21's:

Module 0.0.21, as its README measured it 0.0.22
JavaScript 5,747,880 / 1,327,957 4,876,583 / 1,227,452
Python without torch 7,562,298 / 1,694,759 6,519,418 / 1,597,418
Complete, torch built in 9,479,934 / 2,046,911 8,443,452 / 1,950,080

That is 15.2%, 13.8% and 10.9% smaller raw, and 7.6%, 5.7% and 4.7% smaller
on the wire; the torch package is unchanged at about 0.38 MB. The bytes came
out of tables and duplicated code, not features: Unicode normalization reads
ranked bitmaps instead of hashed tables, the regex properties of strings
share one pool, the UTF-16 and UCS-2 regex matchers share their bodies, cold
error paths and the host preamble are smaller, and the modules are built
without machine paths and post-processed twice.

ZIPP Lite is a new opt-in variant, published as
zipp-wasm-0.0.22-web-lite.zip and built from the source with
./build-variants.sh lite: the published module is 2,633,126 bytes raw and
711,417 after Brotli. It
keeps the JavaScript language, Unicode regex and normalization, BigInt,
eval, collections, proxies, typed arrays, promises and the Engine host API
with its resource limits, and leaves out Intl, Temporal, Python and
torch. zippProfile() reports the variant and what it omits. See the
build variants.

WebAssembly speed

The browser engines interpret, in a checked profile with no unsafe. Two
rounds of profiling that profile itself, each measured against the modules
of the round before on a fixed corpus of 24 to 29 cases under Node 24:

  • The JavaScript module's corpus took 0.90 of the time after the first round
    and 0.89 to 0.90 of that after the second; the two Python modules 0.90 to
    0.92 and then 0.85 to 0.87. No case is slower after the second.
  • An integer loop takes 0.63 to 0.71 of the time and a property read 0.74 to
    0.77 (second round). A statement such as s += i or i++ no longer copies
    its unused value, a register access is one bounds check, and two Numbers
    are added and compared in the dispatch loop.
  • A Python engine starts in 0.65 to 0.69 of the time and a short Python
    program runs in 0.71 to 0.76: programs share the compiled runtime instead
    of copying its 2,300 functions each.
  • Four workloads whose cost grew with the square of a string's length now
    grow with its length. In the JavaScript module: loading a script with
    300 KB of non-ASCII text, 5.3 s to 3 ms; a sticky-regex tokenizer over
    190 KB, 17.8 s to 164 ms; a re.exec loop over 280,000 units of accented
    text, 32.6 s to 33 ms; indexOf from a moving position over 229 KB,
    202 ms to 30 ms.
  • A loop that created and dropped large Unicode-class RegExps ended with
    "script exceeded its memory budget"; compiled programs now count toward
    the collection trigger and the same loop holds 1 to 5 MiB.

A host-visible change: because loops run fewer instructions, the same
program charges fewer steps against an instruction budget than it did
(for (let i = 0; i < n; i++) s += i charges four steps an iteration, not
six). A budget tuned to 0.0.21's counts buys more work.

These figures are from one Windows machine; the measurements, the gates and
what was not measured are in the
validation notes.

The app bridge

A host can now answer synchronous calls the application defines, beside the
fixed storage and clipboard operations: engine.setAppBridge({ call(kind, args) { ... } }), a grant for each kind through
setSyncHostCapabilities(["app.fs.read"]), and host.callSync("fs.read", ...) in the guest. Kinds are checked for shape and for a grant before the
bridge is touched, results cross as JSON, and the synchronous envelope's
argument and byte ceilings apply in both directions. See the
host API.

Native CLI

Member calls on Maps, Sets and strings, split into three instructions by
0.0.15's spec-order calls, are served by the native tiers again: the 13
JavaScript benchmark rows take about 11% less time, and the headline ten are
at 0.986x of Node 24 in an ordinary, not profile-guided, release build. The
Windows CLI delay-loads the GPU runtime's system libraries and starts in
6.3 ms instead of 8.9.

zipp py reads a project's data files when the program opens them, so a
script run from a large checkout starts in 62 ms instead of 460, and its
code cache is bounded by size and last use. The Python suite is at about
1.8x of CPython 3.13 on in-script time; this release did not work on it.

Fixes

  • k++ on a const local threw its TypeError after changing the constant,
    and f++ inside function f replaced the function (and threw nothing in
    strict code). Both leave the binding alone now, as other engines do.
  • Dependency updates, including a patched undici in the site's tooling.

Test262 passes with the same nine documented expected failures as before
(95,671 of 95,680 executions).

Publishing

As for 0.0.21, the engines the site serves are refreshed AFTER this release
exists, in one commit that:

  1. sets zippEngineRelease in landing/package.json to 0.0.22;
  2. refreshes landing/public/playground-runtime from the
    zipp-wasm-0.0.22-web-python asset (sync-playground.mjs --refresh-engine)
    and landing/public/wasm from zipp-wasm-0.0.22-web, both SHA256SUMS-verified;
  3. updates the version, size and SHA-256 that landing/src/App.tsx and
    landing/README.md state about the bundled engine.

What's Changed

  • Add the app host bridge and update dependencies [skip ci] by @izuc in #31

Full Changelog: v0.0.21...v0.0.22