ADR-003 — WasmGC over linear memory

Status: Accepted Date: 2026-04-27

Context

A JavaScript-to-Wasm compiler must place JS heap objects somewhere. There are two viable representations in Wasm today: linear memory (with a hand-written garbage collector), and WasmGC reference types (the host runtime manages the heap, and structs and arrays are first-class typed values).

Linear memory requires the compiler to ship its own collector — mark/sweep or compacting — and to implement allocation, free lists, layout, and root scanning. None of that work is incremental; the collector either is correct or it is not. The collector also runs on every host that loads the module, duplicating work the host's GC is already doing for externref and host values.

WasmGC, by contrast, gives the host runtime responsibility for the JS heap. Struct and array types are declared in the module's type section, allocated with struct.new / array.new, and collected by the host. WasmGC struct types map naturally to JS object shapes (fields with declared types, optional mutability), which is exactly what the closed-world specialization in ADR-001 is producing. Cycles between WasmGC values and host externref values are collected uniformly.

Decision

Use the WasmGC type system as the compilation target for JS values. JS objects, classes, closures, and arrays are lowered to WasmGC struct and array types. The compiler does not implement a garbage collector.

Consequences

Positive: no GC implementation cost; correctness of collection is delegated to the host; struct types are a natural fit for the static path of ADR-001 and for Component Model record types; cycles between compiled values and host externref are uniformly handled.

Negative: requires a WasmGC-capable host (wasmtime 44+, Chrome 119+, Firefox 120+). Hosts without WasmGC cannot run the output. Some structural operations that are trivial in linear memory (raw memory copies, in-place type punning) are not expressible directly and require explicit conversion.

Alternatives rejected