Web-shaped APIs
On this page 8
zig-js is not a browser and ships no DOM. It does implement the host-shaped APIs that server-side runtimes and embedders expect, so a JavaScript runtime built on this engine does not have to reimplement them.
Timers
Context-owned setTimeout, clearTimeout, setInterval, clearInterval.
Scheduling returns immediately; callbacks run only on the event loop that created
the timer. Handles are stable objects with ref(), unref(), hasRef(), and
refresh(). Full details: Timers.
URLs
URL and URLSearchParams, including origin/host/port parsing, percent
encoding, and IDNA handling via the checked-in unicode_idna_data.zig tables.
Text encoding
TextEncoder and TextDecoder over the generated codec tables
(text_codec.zig, text_codec_tables.zig, encoding_multibyte*.zig,
encoding_singlebyte_data.zig), covering the single-byte and multi-byte legacy
encodings alongside UTF-8, with the standard streaming and fatal/replacement
behaviours.
btoa and atob provide base64 at the global level.
Fetch data types
Headers, Request, Response, FormData, and Blob are implemented as data
types — header normalization and guard rules, body consumption
(text/json/arrayBuffer/blob/formData), multipart parsing, and
Blob slicing. Header semantics live in
src/fetch_headers.zig.
There is no network stack. These types exist so an embedder can wire its own transport to standard shapes; the engine performs no I/O.
Cancellation
AbortController and AbortSignal, including AbortSignal.timeout() and the
abort-reason propagation that consumers check. Signal timeout generations are
tracked by the Context, so a torn-down context cannot fire a stale abort.
Structured clone
structuredClone() uses the same wire format as Worker postMessage
(src/structured_clone.zig):
cyclic graphs, Map/Set/Date/RegExp/Error, typed arrays and
DataView, ArrayBuffer transfer (the source detaches), and
SharedArrayBuffer retention (shared, not copied).
Microtasks and the run loop
queueMicrotask shares the promise-reaction queue. The host drains microtasks at
defined checkpoints; timers are a separate macrotask stage. Harness globals
drainMicrotasks, $drainRunLoop, and $drainFinalizationCleanup let a test
host step the loop deterministically — they are harness surface, not stable
embedder API.
What an embedder still owns
- Networking, filesystem, process, and stdio.
- Module specifier resolution and loading (
Context.evaluateModuletakes a host hook — see Embedding). - Logging: there is no
console. - The event-loop policy itself. The engine exposes the queues and the drain points; the run loop is the host's.