ApolloVM Wasm
Native (Dart VM) WebAssembly execution for ApolloVM.
ApolloVM compiles its AST to Wasm on the fly, on every platform, without any
third-party toolchain. Running a compiled module is what needs an engine: browsers ship one, the
Dart VM does not. This package supplies the VM engine, backed by wasm_run.
Why a Separate Package?
The native engine brings an FFI/Rust toolchain with it (wasm_run → flutter_rust_bridge). Keeping
it here means package:apollovm — widely used only to parse, translate and generate code — never
drags that cost, nor its dependency constraints, into consumers that never execute Wasm.
apollovm |
apollovm + apollovm_wasm |
|
|---|---|---|
| Parse / translate / generate | ✅ | ✅ |
| Compile to Wasm | ✅ | ✅ |
| Execute Wasm in the browser | ✅ | ✅ |
| Execute Wasm on the Dart VM | ❌ | ✅ |
| Native / FFI toolchain pulled in | no | yes |
Without this package, WasmRuntime() on the Dart VM reports isSupported == false: Wasm still
compiles, it just cannot be executed.
Usage
Add both packages:
dependencies:
apollovm: ^2.0.0
apollovm_wasm: ^1.1.0
The native library is downloaded (never built) by the wasm_run build hook, which the SDK runs
for you on dart run, dart test and dart compile — no install step. It lands in
.dart_tool/lib/, and WASM_RUN_DART_DYNAMIC_LIBRARY overrides that path if you ship your own.
Requires Dart >= 3.10 (build hooks). Earlier
apollovm_wasmreleases usedwasm_run0.1, whosedart run wasm_run:setupcommand no longer exists.
Register the runtime, and WasmRuntime() returns an engine that executes:
import 'package:apollovm/apollovm.dart';
import 'package:apollovm_wasm/apollovm_wasm.dart';
void main() {
registerApolloVMWasmRuntime();
var runtime = WasmRuntime()..ensureBooted();
print(runtime.isSupported); // true
}
Compiling Dart to Wasm, then executing it
import 'package:apollovm/apollovm.dart';
import 'package:apollovm_wasm/apollovm_wasm.dart';
void main() async {
registerApolloVMWasmRuntime();
// Compile: this half is core `apollovm`.
var vm = ApolloVM();
await vm.loadCodeUnit(SourceCodeUnit('dart', r'''
int sumTo(int limit) {
int sum = 0;
for (int i = 1; i <= limit; ++i) {
sum += i;
}
return sum;
}
''', id: 'test'));
var storageWasm = vm.generateAllIn<BytesOutput>('wasm');
var wasmModules = await storageWasm.allEntries();
var wasmBytes = wasmModules.values.first.values.first.output();
// Execute: this half is what `apollovm_wasm` makes possible on the VM.
var wasmVM = ApolloVM();
await wasmVM.loadCodeUnit(
BinaryCodeUnit('wasm', wasmBytes, id: 'test.wasm', namespace: ''));
var runner = wasmVM.createRunner('wasm')!;
var result =
await runner.executeFunction('', 'sumTo', positionalParameters: [10]);
print(result.getValueNoContext()); // 55
}
WebAssembly GC
The wasm_run backend (wasmtime 14 / wasmi 0.31) does not implement the WebAssembly GC
proposal. Modules that rely on it run in the browser (Chrome 119+), not on this runtime.
Known issue: macOS on Apple Silicon, JIT mode
The wasm_run 0.2.0 prebuilt aarch64-apple-darwin library is killed by macOS
(SIGKILL, Code Signature Invalid) the moment wasmtime executes JIT-compiled Wasm inside the
JIT Dart VM — i.e. under dart run and dart test. Compiling and instantiating modules is
fine; only the call into generated code trips it.
Ahead-of-time compilation is unaffected (its binaries are not hardened-runtime signed), so on
macOS arm64 run Wasm through dart test --compiler exe / dart compile exe. The check is a macOS
code-signing enforcement, so other platforms are not expected to hit it — Linux is verified in CI.
Tracked upstream at wasm_run.
See Also
apollovm— the VM itself: parsing, translation, execution and Wasm compilation.wasm_run— the native Wasm engine this package binds to.
Features and bugs
Please file feature requests and bugs at the issue tracker.
Author
Graciliano M. Passos: gmpassos@GitHub.
Sponsor
Don't be shy, show some love, and become our GitHub Sponsor. Your support means the world to us, and it keeps the code caffeinated! ☕✨
Thanks a million! 🚀😄
License
Libraries
- apollovm_wasm
- Native (Dart VM) WebAssembly execution for ApolloVM.