Golem JavaScript Runtime (QuickJS)
Both TypeScript and Scala (via Scala.js) Golem agents compile to JavaScript and run inside a QuickJS -based WebAssembly runtime provided by wasm-rquickjs .
Language Support
The runtime supports ES2020 including modules, async/await, async generators, Proxies, BigInt, WeakRef, FinalizationRegistry, and all standard built-ins (Array, Map, Set, Promise, RegExp, Date, JSON, Math, typed arrays, etc.).
Available Web Platform APIs
The following browser/web APIs are available out of the box — no imports needed:
- HTTP:
fetch,Headers,Request,Response,FormData - Files/Blobs:
Blob,File - URLs:
URL,URLSearchParams - Console:
console - Timers:
setTimeout/clearTimeout,setInterval/clearInterval,setImmediate - Abort:
AbortController,AbortSignal - Encoding:
TextEncoder,TextDecoder,TextEncoderStream,TextDecoderStream - Streams:
ReadableStream,WritableStream,TransformStream - Structured clone:
structuredClone - Crypto:
crypto.randomUUID,crypto.getRandomValues - Events:
Event,EventTarget,CustomEvent - Messaging:
MessageChannel,MessagePort - Errors:
DOMException - Internationalization:
Intl(DateTimeFormat, NumberFormat, Collator, PluralRules)
Available Node.js Modules
These Node.js-compatible modules can be imported:
| Module | Description |
|---|---|
node:buffer | Buffer API |
node:child_process | Constrained in-runtime JavaScript execution; no host processes or general shell |
node:crypto | Hashes, HMAC, ciphers, key generation, sign/verify, DH, ECDH, X509, etc. |
node:dgram | UDP sockets |
node:dns | DNS resolution |
node:events | EventEmitter |
node:fs, node:fs/promises | Comprehensive filesystem API (read, write, stat, mkdir, readdir, etc.) |
node:http, node:https | HTTP client and server |
node:module | Module utilities |
node:net | TCP sockets and servers |
node:os | OS information |
node:path | Path manipulation |
node:perf_hooks | Performance measurement |
node:process | Process information |
node:punycode | Punycode encoding |
node:querystring | Query string parsing |
node:readline | Readline interface |
node:sqlite | Embedded SQLite (requires feature flag) |
node:stream, node:stream/promises | Stream API |
node:string_decoder | String decoding |
node:test | Test runner |
node:timers | Timer APIs |
node:url | URL parsing |
node:util | Utility functions |
node:v8 | V8 compatibility shim |
node:vm | Script evaluation |
node:zlib | Compression (gzip, deflate, brotli) |
Stub Modules (Throw or No-op)
These modules exist for compatibility but will throw or no-op when used:
node:clusternode:http2node:inspectornode:tlsnode:worker_threads
npm Package Compatibility
Additional npm packages can be installed with npm install (TypeScript) or added as Scala.js-compatible dependencies (Scala). Most packages targeting browsers or using the Node.js APIs listed above will work. Packages that depend on native C/C++ bindings or JVM-specific APIs will not work.
The runtime’s node:child_process adapter can run JavaScript targets, supported Node shebang files,
and npm’s simple node <script> command form. It cannot create host processes, run a general shell,
or execute native binaries. Unsupported commands fail explicitly.
Fresh JavaScript Execution
wasm-rquickjs:execution runs asynchronous JavaScript jobs in fresh QuickJS runtimes for both
TypeScript and Scala agents. Use startJavaScript for live output and cancellation, or
runJavaScript for collected output. TypeScript agent templates additionally transform entry files
ending in .ts, .mts, or .cts at runtime, and accept inline TypeScript with
language: 'typescript'. The Scala runtime does not include this TypeScript transformation. The
transformation transpiles syntax but does not type-check or read tsconfig.json.
Each job receives an explicit environment allowlist and fresh globals, process state, timers, and module caches. Jobs still share the component filesystem and host capabilities, so this is not a security sandbox. Always provide a positive timeout for untrusted or potentially CPU-bound code.
File I/O
Use node:fs or node:fs/promises for filesystem operations. This is the standard way to read/write files in both TypeScript and Scala agents.
TypeScript
import * as fs from 'node:fs';
// Synchronous
const content = fs.readFileSync('/data/config.json', 'utf-8');
// Async
import * as fsp from 'node:fs/promises';
const data = await fsp.readFile('/data/config.json', 'utf-8');Scala (via Scala.js interop)
import scala.scalajs.js
import scala.scalajs.js.annotation.JSImport
@js.native
@JSImport("node:fs", JSImport.Namespace)
private object Fs extends js.Object {
def readFileSync(path: String, encoding: String): String = js.native
def writeFileSync(path: String, data: String): Unit = js.native
def existsSync(path: String): Boolean = js.native
}
// Usage
val content = Fs.readFileSync("/data/config.json", "utf-8")Important (Scala.js): WASI modules like
node:fsare not available during the build-time pre-initialization (wizer) phase — they are only available at runtime. If you importnode:fsat the top level of a Scala.js module, the import executes during pre-initialization and will fail. Use lazy initialization (lazy val) or defer the import to method bodies to ensure the module is loaded at runtime:// ✅ CORRECT — lazy val defers initialization to first use at runtime private lazy val fs: Fs.type = Fs // ❌ WRONG — top-level val triggers import during pre-initialization private val fs: Fs.type = Fs
Reference
Check the wasm-rquickjs README for the most up-to-date list of available APIs.
Looking up Golem SDK signatures
The full TypeScript type definitions for the Golem SDK live at:
node_modules/@golemcloud/golem-ts-sdk/dist/index.d.mtsGrep there (and in the dist/host/ and dist/lib/ subdirectories under the same package) when
you need the exact signature of a helper such as withIdempotenceMode, atomically,
withRetryPolicy, Duration, Predicate, Policy, NamedPolicy, etc. The shipped
dist/index.mjs is a single-line minified bundle and is not a useful reference; always read
the .d.mts instead.