DotWasm.Encoding
0.1.0
dotnet add package DotWasm.Encoding --version 0.1.0
NuGet\Install-Package DotWasm.Encoding -Version 0.1.0
<PackageReference Include="DotWasm.Encoding" Version="0.1.0" />
<PackageVersion Include="DotWasm.Encoding" Version="0.1.0" />
<PackageReference Include="DotWasm.Encoding" />
paket add DotWasm.Encoding --version 0.1.0
#r "nuget: DotWasm.Encoding, 0.1.0"
#:package DotWasm.Encoding@0.1.0
#addin nuget:?package=DotWasm.Encoding&version=0.1.0
#tool nuget:?package=DotWasm.Encoding&version=0.1.0
DotWasm
A WebAssembly runtime implemented in C# for .NET
DotWasm is currently in alpha. It is not suitable for production use and may undergo breaking changes without notice.
Overview
DotWasm is an experimental WebAssembly runtime written in C#. It is implemented in 100% pure C# and supports nearly all WebAssembly 3.0 proposals, including Wasm GC.
Features
- Implemented entirely in pure C#
- Implements WebAssembly 3.0–equivalent proposals (excluding Threads)
- Nearly 100% passing the official test suite
- No dynamic code generation; compatible with NativeAOT
Requirements
DotWasm requires .NET 10.0 or above.
.NET CLI
dotnet add DotWasm
Package Structure
Quick Start
;; example.wat
(module
(func $add (param $x i32) (param $y i32) (result i32)
local.get $x
local.get $y
i32.add
)
(export "add" (func $add))
)
using DotWasm.Encoding;
using DotWasm.Runtime;
var bytes = File.ReadAllBytes("example.wasm");
var module = WasmEncoding.Decode(bytes);
var store = new WasmStore();
var linker = new WasmLinker(store);
var instance = linker.Instantiate(module);
Span<WasmValue> results = new WasmValue[1];
instance.Invoke("add", [1, 2], results);
int result = results[0].I32;
Console.WriteLine(result); // 3
Retrieving Exports
You can obtain exported globals, memories, etc. from the Wasm side using the instance.TryGetExported**() family of methods.
;; example.wat
(module
(global $g (export "my_global") (mut i32) (i32.const 42))
)
var instance = linker.Instantiate(module);
if (instance.TryGetExportedGlobal("my_global", out var global))
{
Console.WriteLine(global.Value.I32);
global.Value = 100;
}
Integrating with Host Environment
Through the WasmLinker API you can provide host functions, memories, and other imports to the Wasm side.
var addFunc = new HostFunction
{
Type = new FuncType
{
Parameters = [WasmTypes.I32, WasmTypes.I32],
Results = [WasmTypes.I32],
},
Delegate = static (ReadOnlySpan<WasmValue> args, Span<WasmValue> results) =>
{
var a = args[0].I32;
var b = args[1].I32;
results[0] = WasmValue.FromI32(a + b);
},
};
linker.RegisterFunction("env", "hostAdd", addFunc);
var memory = new MemoryInstance(1);
source.CopyTo(memory.Data);
linker.RegisterMemory("env", "hostMemory", memory);
var global = new GlobalInstance
{
Mutable = true,
ValueType = WasmTypes.I32,
Value = 43,
};
linker.RegisterMemory("env", "hostGlobal", global);
ExternalReference
You can pass opaque host references to the Wasm side as ExternalReference.
var gameObject = new GameObject("obj");
var global = new GlobalInstance
{
Mutable = true,
ValueType = WasmTypes.ExternRef(isNullable: false),
Value = ExternalReference.Create(gameObject),
};
linker.RegisterMemory("env", "object", global);
Proposals
DotWasm currently supports the following proposals:
| Proposal | Status | Note |
|---|---|---|
| WebAssembly 1.0 Core Spec | ✅ | |
| Mutable Globals | ✅ | |
| Sign-extension operators | ✅ | |
| Non-trapping Float-to-int Conversions | ✅ | |
| Multi-value | ✅ | |
| Bulk Memory Operations | ✅ | |
| Reference Types | ✅ | |
| SIMD | ✅ | |
| Component Model | ❌ | |
| Relaxed SIMD | ✅ | |
| Multi Memory | ✅ | |
| Tail Call | ✅ | |
| Extended Constant Expressions | ✅ | |
| Memory64 | ✅ | |
| Exception Handling | ✅ | |
| Typed Function References | ✅ | |
| GC | ✅ | |
| Threads | ❌ |
Performance
DotWasm is designed to minimize dynamic GC allocations, but it is not currently heavily optimized for execution speed. Because DotWasm avoids dynamic code generation to support AOT, its performance lags significantly behind JIT-based runtimes like Wasmtime.
Below are benchmark results for converting a 128x128 image to grayscale.
| Method | Mean | Error | StdDev |
|---|---|---|---|
| Wasmtime | 20.79 us | 0.520 us | 1.493 us |
| WaaS | 4,713.03 us | 94.249 us | 141.067 us |
| DotWasm | 11,470.14 us | 217.310 us | 213.428 us |
| WACS | 14,586.17 us | 285.006 us | 279.914 us |
The comparison used the following libraries:
As shown above, DotWasm is considerably slower. This is a known issue and is planned to be improved before a stable release.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. net11.0 is compatible. |
-
net10.0
- DotWasm.Models (>= 0.1.0)
-
net11.0
- DotWasm.Models (>= 0.1.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on DotWasm.Encoding:
| Package | Downloads |
|---|---|
|
DotWasm.Runtime
Runtime implementation for DotWasm. |
|
|
DotWasm.Validation
Validation logic for DotWasm. |
|
|
DotWasm
A WebAssembly runtime implemented in C# for .NET |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0 | 91 | 5/27/2026 |