Global objects

esrun's global scope tracks the WinterTC Minimum Common Web Platform API. These are standard Web globals — the same names you would use in a browser or other server runtimes. Host capabilities (filesystem, process, network access) are not globals; they live in runtime: modules.

Core

GlobalNotes
globalThis
self
consolefull Console Standard set — see below
queueMicrotask
structuredClone
reportError
navigatoruserAgent — "ES-Runtime/<version>"; hardwareConcurrency — the CPU count a worker pool is sized from
prompt, confirm, alertAsk the person at the terminal, synchronously, as on the web. The question goes to standard error. With no terminal on stdin they return at once (null, false, undefined). See stdin.

console

GroupMethods
Outputlog, info, warn, error, debug, dir, dirxml, trace
Groupinggroup, groupCollapsed, groupEnd
Countingcount, countReset
Timingtime, timeLog, timeEnd
Otherassert, table, clear

Format specifiers: %s, %d/%i, %f, %o/%O, %j, %%, %c.

JavaScript
console.table([{ id: 1, name: "a" }, { id: 2, name: "b" }]);
console.time("query"); await db.run(); console.timeEnd("query");

Timers

GlobalNotes
setTimeout / clearTimeout
setInterval / clearInterval

URL

GlobalNotes
URLcanParse, parse, createObjectURL / revokeObjectURL
URLSearchParams
URLPattern369/369 on the official WPT suite

Fetch & networking

GlobalNotes
fetchstreaming request + response bodies; all three redirect modes
Request
Responseredirected + final url from the transport
Headersincl. getSetCookie
WebSocketclient; server is runtime:websocket
WebSocketStreamstreams interface over the same connection

Encoding

GlobalNotes
TextEncoder / TextDecoderencoder is UTF-8; decoder takes every WHATWG label (utf-16le, windows-1252, shift_jis, …)
TextEncoderStream / TextDecoderStream
atob / btoa

Streams

GlobalNotes
ReadableStreamdefault + byte/BYOB, from, async iteration
WritableStream
TransformStream
ByteLengthQueuingStrategy
CountQueuingStrategy
CompressionStream / DecompressionStreamgzip, deflate, deflate-raw, brotli

Crypto

GlobalNotes
cryptogetRandomValues, randomUUID
CryptoKey
crypto.subtleAlgorithms
digestSHA-1/256/384/512
sign / verifyHMAC, Ed25519, ECDSA (P-256/384/521), RSASSA-PKCS1-v1_5, RSA-PSS
encrypt / decryptAES-GCM/CBC/CTR, RSA-OAEP
wrapKey / unwrapKeyAES-KW, AES-GCM/CBC/CTR, RSA-OAEP
deriveBits / deriveKeyHKDF, PBKDF2, ECDH, X25519
key formatsraw, spki, pkcs8, jwk (oct for symmetric, OKP for Ed25519/X25519)

Events

GlobalNotes
Event / EventTarget / CustomEvent
MessageEvent / CloseEvent
ErrorEvent / ProgressEvent / PromiseRejectionEvent
AbortController / AbortSignal
addEventListener / removeEventListener / dispatchEventon the global scope

Unhandled failures

A failure with nothing left to catch it is offered to the global scope first. preventDefault() claims it; anything unclaimed is printed and exits non-zero.

EventFired whenCancelable
erroran exception escapes a timer callback, or reportError()yes
unhandledrejectiona rejection is unhandled at the end of a tickyes
rejectionhandleda handler attaches to an already-reported rejectionno
JavaScript
globalThis.addEventListener("unhandledrejection", (event) => {
  logger.warn("unhandled", event.reason);
  event.preventDefault(); // mine now — do not fail the process
});

onerror / onunhandledrejection / onrejectionhandled are single-handler slots over the same events. rejectionhandled does not retract a report that has already gone out.

Messaging

Messages are structured-cloned at postMessage, delivered in order, and reach other agents — a worker is a second isolate on its own thread. See Workers.

GlobalNotes
Workermodule workers only; starts with no capabilities, granted per spawn; { memory } caps its heap
MessageChannel / MessagePorta port buffers until start(); assigning onmessage starts it
BroadcastChannelreaches every open channel of the same name except itself, in creation order

A MessagePort may be transferred and may not be cloned — two ends of a channel cannot become three — and arrives through event.ports. ArrayBuffer and streams transfer too; a SharedArrayBuffer is shared rather than transferred, which is what makes Atomics between agents mean anything.

Inside a worker the global scope is a DedicatedWorkerGlobalScope, with WorkerNavigator and WorkerLocation alongside it.

Data

GlobalNotes
Blob
File
FormData
DOMException

Performance

GlobalNotes
performancenow(), timeOrigin, User Timing (mark/measure/getEntries*/clear*)
PerformanceEntry / PerformanceMark / PerformanceMeasure

WebAssembly

No capability required — a module is as privileged as the imports you pass it.

JavaScript
const { instance } = await WebAssembly.instantiate(bytes, {
  env: { log: (n) => console.log(n) },
});
instance.exports.add(2, 3); // 5

import { add } from "./add.wasm"; // .wasm files import directly

Full surface, proposal matrix, and caveats: WebAssembly & WASI.

Streaming upload

Passing a ReadableStream as the fetch body uploads it as a chunked transfer with backpressure — the body is never fully buffered, so large or open-ended uploads stay memory-bounded. Response bodies stream too.

JavaScript
// A ReadableStream body streams to the server (chunked upload, backpressured).
const body = new ReadableStream({
  async pull(c) {
    const next = await source.read();        // your data source
    if (next.done) c.close();
    else c.enqueue(next.value);              // Uint8Array chunks
  },
});

await fetch("https://example.com/upload", { method: "POST", body });
// Anything else (string, Blob, FormData, Uint8Array) is sent buffered.

Timeouts

Connect (DNS + TCP + TLS)30s → ERR_TIMED_OUT
TCP keepalive60s on pooled connections
Whole requestuncapped — a streaming body may be long-lived by design
JavaScript
await fetch(url, { signal: AbortSignal.timeout(5000) }); // TimeoutError

Compressed responses

SentAccept-Encoding: gzip, br, deflate
Decodedgzip, br, deflate — off the response's Content-Encoding
StrippedContent-Encoding, Content-Length
Passed throughany other coding (zstd, …), headers intact

Requests carry User-Agent: ES-Runtime/<version> unless you set your own. Both are properties of the default transport.

Redirects

redirectBehaviour
"follow" (default)follows, cap 20; past it ERR_TOO_MANY_REDIRECTS
"manual"resolves with the 3xx, Location intact
"error"rejects with TypeError
JavaScript
const r = await fetch(url, { redirect: "manual" });
r.status;                      // 302
r.headers.get("location");     // where it would have gone
r.redirected;                  // false — nothing was followed

An unknown mode throws TypeError from new Request. Under "manual" the real response is returned, not the spec's opaque-redirect filtered one — same as Node, Deno and Bun.

Not available

GlobalWhy not
process / Buffer / requireNode.js globals — not provided (use runtime: modules)
SharedWorkershares one worker between documents, and there are none
localStorage / windowbrowser globals — out of scope
navigator.* beyond userAgent and hardwareConcurrencydocument/device/permission surface — out of scope; a plausible answer would make a feature check pass and lie
Last updated on
Edit this page