A pure Dart WebAssembly runtime for Dart and Flutter ecosystems.
WASD provides Dart-native WebAssembly execution with a pure Dart core runtime layer, so you can embed and run Wasm modules directly from Dart code without relying on a native runtime dependency in the core library.
WASD is a Dart package for:
- Decoding and validating WebAssembly binaries
- Compiling and instantiating modules from bytes or streams
- Instantiating modules with host imports
- Executing exported functions from Dart
- Running WASI Preview1 workloads
- Inspecting module imports/exports/custom sections
- Pure Dart core runtime, aligned with Dart/Flutter embedding workflows
- Public API that mirrors WebAssembly-style operations (
compile,instantiate,validate) - Explicit host integration via import maps and typed wrappers
- Built-in WASI Preview1 host surface through
WASI - Regression-oriented tests and conformance tooling in-repo
dart pub add wasdOr add manually in pubspec.yaml:
dependencies:
wasd: ^0.2.0Run included examples:
dart run example/wasm_cli.dart
dart run example/wasm_cli.dart 3 9The Flutter DOOM example has its own guide in
example/doom/README.md.
Minimal module invocation:
import 'dart:typed_data';
import 'package:wasd/wasd.dart';
Future<void> main() async {
final Uint8List wasmBytes = loadYourModuleBytes();
final runtime = await WebAssembly.instantiate(wasmBytes.buffer);
final addExport = runtime.instance.exports['add'];
if (addExport is! FunctionImportExportValue) {
throw StateError('Expected `add` export to be a function.');
}
final result = (addExport.ref([20, 22]) as num).toInt();
print(result); // 42
}
Uint8List loadYourModuleBytes() => throw UnimplementedError();Provide host callbacks with Imports and ImportExportKind.function:
import 'dart:typed_data';
import 'package:wasd/wasd.dart';
Future<void> main() async {
final wasmBytes = loadYourModuleBytes();
final imports = <String, ModuleImports>{
'env': {
'plus': ImportExportKind.function((args) {
final a = args[0] as int;
final b = args[1] as int;
return a + b;
}),
},
};
final runtime = await WebAssembly.instantiate(wasmBytes.buffer, imports);
final usePlus = runtime.instance.exports['use_plus'];
if (usePlus is! FunctionImportExportValue) {
throw StateError('Expected `use_plus` export to be a function.');
}
print(usePlus.ref([4, 5])); // 9
}
Uint8List loadYourModuleBytes() => throw UnimplementedError();Use WASI and call _start through wasi.start(instance).
import 'package:wasd/wasd.dart';
Future<void> main() async {
final wasmBytes = loadWasiModuleBytes();
final wasi = WASI(
args: const ['demo'],
env: const {'FOO': 'bar'},
);
final runtime = await WebAssembly.instantiate(wasmBytes.buffer, wasi.imports);
final exitCode = wasi.start(runtime.instance);
print('exitCode=$exitCode');
}
Uint8List loadWasiModuleBytes() => throw UnimplementedError();import 'dart:typed_data';
import 'package:wasd/wasd.dart';
Future<void> main() async {
final wasmBytes = loadYourModuleBytes();
final module = await WebAssembly.compile(wasmBytes.buffer);
final imports = Module.imports(module);
final exports = Module.exports(module);
print('imports=${imports.length} exports=${exports.length}');
}
Uint8List loadYourModuleBytes() => throw UnimplementedError();dart analyze
dart test test/wasi_test.dart test/wasm_test.dart| Item | Version | Status |
|---|---|---|
| Core Wasm module binary | 0x01 0x00 0x00 0x00 |
Supported |
| WASI Version | Status |
|---|---|
| Preview 1 | Supported |
| Preview 2 | Not implemented |
| Preview 3 | Not implemented |
- Some proposal/component forms are intentionally guarded and may return
UnsupportedErroruntil implemented. - JS runtime behavior is environment-dependent: Node.js uses
node:wasi; browsers provide a minimalwasi_snapshot_preview1shim for command-style flows (proc_exit,args_*,environ_*,random_get,fd_read,fd_write,fd_fdstat_get,fd_filestat_get,fd_prestat_*,fd_close,clock_time_get) and virtual filesystem basics (fd_seek,path_open,path_filestat_get), with explicitENOSYSstubs for unsupported calls (for examplepath_unlink_file,proc_raise,sock_*). - Native preview1 host support intentionally tracks the same minimal surface as the browser shim: command-style flows plus virtual filesystem basics (
fd_seek,path_open,path_filestat_get), while unsupported preview1 syscalls stay as explicitENOSYSstubs.
Contributions for missing features and edge-case regressions are welcome.
Contributions are welcome through pull requests and issues.
- Follow existing lint/style rules (
dart format .,dart analyze) - Add focused regression tests for behavior changes
- Keep changes scoped and reproducible with command output
WASD is licensed under the MIT License. See LICENSE.