Garbage Collection
WasmEdge supports the WebAssembly Garbage Collection (GC) proposal starting from version 0.14.0. This allows high-level languages like Kotlin, Dart, and OCaml to compile to WebAssembly without bundling their own garbage collector, resulting in smaller binaries and better runtime performance.
What is Wasm GC?
Normally, WebAssembly manages memory manually — programs allocate and free memory themselves using linear memory. The GC proposal adds first-class garbage-collected types: structs (fixed heterogeneous fields) and arrays (homogeneous elements), both allocated on the heap and automatically reclaimed when no longer reachable.
This is enabled by default in WasmEdge since 0.16.0. For WasmEdge 0.14.x–0.15.x, enable it explicitly with the (deprecated) --enable-gc flag; you can disable GC with --disable-gc when needed.
Prerequisites
- WasmEdge
0.14.0or later. See the installation guide. wasm-tools, to compile.watsource files to.wasm.
Install wasm-tools on Linux (x86_64):
curl -LO https://github.com/bytecodealliance/wasm-tools/releases/download/v1.262.0/wasm-tools-1.262.0-x86_64-linux.tar.gz
tar -xzf wasm-tools-1.262.0-x86_64-linux.tar.gz
sudo install wasm-tools-1.262.0-x86_64-linux/wasm-tools /usr/local/bin/wasm-tools
Or on macOS:
brew install wasm-tools
For other platforms, see the wasm-tools installation instructions.
Example: Working with Structs
The following WAT (WebAssembly Text Format) example defines a $point struct with two i32 fields, allocates one, sets a field, and returns a value from it.
Create a file called point.wat:
(module
(type $point (struct (field $x (mut i32)) (field $y (mut i32))))
(func (export "make_point") (result i32)
(local $p (ref $point))
;; Allocate a new $point struct with x=10, y=20
(local.set $p
(struct.new $point (i32.const 10) (i32.const 20))
)
;; Update x to 99
(struct.set $point $x (local.get $p) (i32.const 99))
;; Return the value of x
(struct.get $point $x (local.get $p))
)
)
Compile it to a .wasm binary:
wasm-tools parse point.wat -o point.wasm
Run it with WasmEdge:
wasmedge --reactor point.wasm make_point
Expected output:
99
Example: Working with Arrays
The following example creates a GC-managed array of i32 values, fills it with a value, and reads back an element.
Create a file called array.wat:
(module
(type $int_array (array (mut i32)))
(func (export "array_example") (result i32)
(local $a (ref $int_array))
;; Allocate an array of length 5, initialized to 0
(local.set $a
(array.new_default $int_array (i32.const 5))
)
;; Set element at index 2 to 42
(array.set $int_array (local.get $a) (i32.const 2) (i32.const 42))
;; Return element at index 2
(array.get $int_array (local.get $a) (i32.const 2))
)
)
Compile and run:
wasm-tools parse array.wat -o array.wasm
wasmedge --reactor array.wasm array_example
Expected output:
42
Disabling GC
If you need to run a Wasm module without GC support (for example, to test compatibility), pass the --disable-gc flag:
wasmedge --disable-gc your_module.wasm
C API
To configure GC support programmatically via the WasmEdge C API, use the WasmEdge_Proposal_GC enumeration value:
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
// WasmEdge 0.16.0+ enables GC by default; to disable it:
WasmEdge_ConfigureRemoveProposal(ConfCxt, WasmEdge_Proposal_GC);
// WasmEdge 0.14.x–0.15.x has GC off by default; to enable it instead:
// WasmEdge_ConfigureAddProposal(ConfCxt, WasmEdge_Proposal_GC);
Language Support
Languages that compile to Wasm GC and can run on WasmEdge include:
- Kotlin/Wasm — via the Kotlin compiler's
wasmGctarget - Dart — via
dart compile wasm - OCaml — via the
wasm_of_ocamlcompiler
For language-specific guides, refer to each toolchain's documentation on enabling WebAssembly GC support in its Wasm backend.