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 | Partial, actively expanding |
| Preview 2 | Not implemented |
| Preview 3 | Not implemented |
- Some proposal/component forms are intentionally guarded and may return
UnsupportedErroruntil implemented. WASI(version: WASIVersion.preview2)andWASI(version: WASIVersion.preview3)are explicit future-facing version choices and currently throwUnsupportedError; only Preview1 host instantiation is implemented.- JS runtimes use the in-repo
wasi_snapshot_preview1host on both Node.js and browsers, notnode:wasi, for command-style flows (proc_exit,proc_raisethrough an optionalprocRaiseHandler,args_*,environ_*,random_get, configured-stdinfd_read,fd_write, socketfd_read/fd_write,fd_pread,fd_pwrite,fd_tell,fd_advise,fd_datasync,fd_sync,fd_allocate,fd_fdstat_get,fd_fdstat_set_flags,fd_fdstat_set_rights,fd_filestat_get,fd_filestat_set_size,fd_filestat_set_times,fd_prestat_*,fd_close,fd_renumber,clock_time_get,poll_oneoffclock/file/socket readiness) and virtual filesystem basics (fd_seek,fd_readdir,path_open,path_filestat_get,path_filestat_set_times, writable in-memory files, path create/link/symlink/readlink/rename/unlink/remove, symlink-follow lookup flags, descriptor rights enforcement, configured Preview1 stream socket descriptors forsock_accept, configured stream/datagram socket descriptors forsock_recv,sock_send,fd_read,fd_write, andsock_shutdown, and host-backed stream/datagram receive/send handlers for injected socket descriptors). JSproc_raisereturnsENOSYSunless a handler is provided. - Native preview1 host support intentionally tracks the same minimal surface as the JS Preview1 host: command-style flows, configured-stdin
fd_read, socketfd_read/fd_write, positioned file IO, descriptor renumbering, descriptor flags/rights/advice/sync for the in-memory VFS, file sizing/allocation, filestat time metadata,poll_oneoffclock/file/socket readiness, virtual filesystem basics (fd_seek,fd_readdir,path_open,path_filestat_get,path_filestat_set_times, writable in-memory files, path create/link/symlink/readlink/rename/unlink/remove, symlink-follow lookup flags, and descriptor rights enforcement), nativeproc_raisesignal delivery or an optionalprocRaiseHandler, configuredWASIPreview1Socketstream descriptors forsock_accept, configured stream/datagram descriptors forsock_recv,sock_send,fd_read,fd_write, andsock_shutdown, and host-backed stream/datagram receive/send handlers for injected socket descriptors. Preview1 does not define socket creation syscalls, so native/JS socket support is descriptor injection rather than a raw networking API.
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.