![]() |
VOOZH | about |
dotnet add package WebAssembly --version 1.3.0
NuGet\Install-Package WebAssembly -Version 1.3.0
<PackageReference Include="WebAssembly" Version="1.3.0" />
<PackageVersion Include="WebAssembly" Version="1.3.0" />Directory.Packages.props
<PackageReference Include="WebAssembly" />Project file
paket add WebAssembly --version 1.3.0
#r "nuget: WebAssembly, 1.3.0"
#:package WebAssembly@1.3.0
#addin nuget:?package=WebAssembly&version=1.3.0Install as a Cake Addin
#tool nuget:?package=WebAssembly&version=1.3.0Install as a Cake Tool
Only WebAssembly 1.0 is supported! Most WASM files target a higher version and will encounter errors if you try to load them with WebAssembly for .NET.
A library able to create, read, modify, write, execute WebAssembly (WASM) files from .NET-based applications. It can also convert WASM files to .NET DLLs. Execution does not use an interpreter or a 3rd party library: WASM instructions are mapped to their .NET equivalents and converted to native machine language by the .NET JIT compiler.
Available on NuGet at https://www.nuget.org/packages/WebAssembly .
WebAssembly.Module class to create, read, modify, and write WebAssembly (WASM) binary files.
Module.ReadFromBinary reads a stream into an instance, which can then be inspected and modified through its properties.
WriteToBinary on a module instance writes binary WASM to the provided stream.WebAssembly.Runtime.Compile class to execute WebAssembly (WASM) binary files using the .NET JIT compiler or convert it to a .NET DLL.
You're welcome to report a bug if you can share a WASM file that has a problem, but no one is actively working on this project so a fix may not come.
using System;
using WebAssembly; // Acquire from https://www.nuget.org/packages/WebAssembly
using WebAssembly.Instructions;
using WebAssembly.Runtime;
// Module can be used to create, read, modify, and write WebAssembly files.
var module = new Module(); // In this case, we're creating a new one.
// Types are function signatures: the list of parameters and returns.
module.Types.Add(new WebAssemblyType // The first added type gets index 0.
{
Parameters =
[
WebAssemblyValueType.Int32, // This sample takes a single Int32 as input.
// Complex types can be passed by sending them in pieces.
],
Returns =
[
// Multiple returns are supported by the binary format.
// Standard currently allows a count of 0 or 1, though.
WebAssemblyValueType.Int32,
],
});
// Types can be re-used for multiple functions to reduce WASM size.
// The function list associates a function index to a type index.
module.Functions.Add(new Function // The first added function gets index 0.
{
Type = 0, // The index for the "type" value added above.
});
// Code must be passed in the exact same order as the Functions above.
module.Codes.Add(new FunctionBody
{
Code =
[
new LocalGet(0), // The parameters are the first locals, in order.
// We defined the first parameter as Int32, so now an Int32 is at the top of the stack.
new Int32CountOneBits(), // Returns the count of binary bits set to 1.
// It takes the Int32 from the top of the stack, and pushes the return value.
// So, in the end, there is still a single Int32 on the stack.
new End(), // All functions must end with "End".
// The final "End" also delivers the returned value.
],
});
// Exports enable features to be accessed by external code.
// Typically this means JavaScript, but this library adds .NET execution capability, too.
module.Exports.Add(new Export
{
Kind = ExternalKind.Function,
Index = 0, // This should match the function index from above.
Name = "Demo", // Anything legal in Unicode is legal in an export name.
});
// We now have enough for a usable WASM file, which we could save with module.WriteToBinary().
// Below, we show how the Compile feature can be used for .NET-based execution.
// For stream-based compilation, WebAssembly.Compile should be used.
var instanceCreator = module.Compile<Sample>(); // Sample is defined later.
// Instances should be wrapped in a "using" block for automatic disposal.
// This sample doesn't import anything, so we pass an empty import dictionary.
using (var instance = instanceCreator(new ImportDictionary()))
{
// FYI, instanceCreator can be used multiple times to create independent instances.
Console.WriteLine(instance.Exports.Demo(0)); // Binary 0, result 0
Console.WriteLine(instance.Exports.Demo(1)); // Binary 1, result 1,
Console.WriteLine(instance.Exports.Demo(42)); // Binary 101010, result 3
} // Automatically release the WebAssembly instance here.
public abstract class Sample
{
// Sometimes you can use C# dynamic instead of building an abstract class like this.
public abstract int Demo(int value);
}
This feature is experimental.
The saving process uses the PersistedAssemblyBuilder feature introduced in .NET 9. Aided by MetadataLoadContext, this example produces a DLL for .NET Standard 2.0.
var resolver = new PathAssemblyResolver([
// A core DLL containing System.String and other basic features:
"C:\\Program Files\\dotnet\\sdk\\9.0.300-preview.0.25177.5\\ref\\netstandard.dll",
// One way or another you'll need a reference to the matching WebAssembly.dll built against the core DLL.
"C:\\dotnet-webassembly\\WebAssembly\\bin\\Release\\netstandard2.0\\WebAssembly.dll"
]);
using var context = new MetadataLoadContext(resolver);
const string name = "HelloWorld"; // Name components should match.
var assembly = Compile.CreatePersistedAssembly(
File.OpenRead("HelloWorld.wasm"), // This is part of the "RunExisting" sample.
new(
context.CoreAssembly,
resolver.Resolve(context, new("WebAssembly")),
new(name),
$"{name}.dll"
)
{
// The type name includes the namespace.
// If not set, defaults to WebAssembly.CompiledFromWasm.
TypeName = "Converted.HelloWorld"
}
);
assembly.Save($"{name}.dll");
To use the new DLL, you directly reference it in your .csproj.
<ItemGroup>
<Reference Include="HelloWorld">
<HintPath>bin\HelloWorld.dll</HintPath>
</Reference>
</ItemGroup>
Once the DLL reference is in place, you can access it just like any other .NET library.
var helloWorld = new Converted.HelloWorld((module, field) =>
{
// Imports are defined by the original WASM and must be supplied by you.
if (module == "env" && field == "sayc")
return new FunctionImport(new Action<int>(raw => Console.Write((char)raw)));
throw new Exception($"Unknown import: {module} {field}");
});
// You can directly access anything exported by the WASM.
var result = helloWorld.main();
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 is compatible. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 is compatible. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 4 NuGet packages that depend on WebAssembly:
| Package | Downloads |
|---|---|
|
ConcordiumNetSdk
A .NET integration library written in C# which adds support for constructing and sending various transactions, as well as querying various aspects of the Concordium blockchain and its nodes. This SDK uses version 2 of the Concordium Node gRPC API to interact with Concordium nodes and in turn the Concordium blockchain. |
|
|
Backlang.Backends.Wasm
A backend for backlang for the bs2k emulation system |
|
|
WebAssembly.FSharp
Provides an idiomatic F# WebAssembly module generation toolkit around the base WebAssembly package. |
|
|
Microsoft.CST.OSSGadget.Shared.CLI
OSS Gadget - Shared CLI Functionality |
Showing the top 1 popular GitHub repositories that depend on WebAssembly:
| Repository | Stars |
|---|---|
|
microsoft/OSSGadget
Collection of tools for analyzing open source packages.
|
| Version | Downloads | Last Updated |
|---|---|---|
| 1.3.0 | 1,131 | 4/20/2025 |
| 1.2.1 | 30,036 | 8/14/2022 |
| 1.2.0 | 8,884 | 5/24/2021 |
| 1.1.0 | 635 | 5/16/2021 |
| 1.0.0 | 598 | 4/24/2021 |
| 0.11.0 | 1,108 | 2/15/2021 |
| 0.10.2-preview | 430 | 1/31/2021 |
| 0.10.1-preview | 542 | 12/26/2020 |
| 0.10.0-preview | 520 | 10/3/2020 |
| 0.9.0-preview | 1,304 | 6/13/2020 |
| 0.8.0-preview | 1,942 | 12/8/2019 |
| 0.7.1-preview | 848 | 8/4/2019 |
| 0.7.0-preview | 590 | 7/27/2019 |
| 0.6.0-preview | 615 | 7/4/2019 |
| 0.5.0-preview | 633 | 7/1/2019 |
| 0.4.0-preview | 626 | 6/24/2019 |
| 0.3.8-preview | 674 | 5/26/2019 |
| 0.3.7-preview | 755 | 2/10/2019 |
| 0.3.6-preview | 748 | 2/3/2019 |
| 0.3.5-preview | 881 | 10/20/2018 |
Full support for creation and modification of WASM 1.0 files; .NET CLR JIT-based execution works well but may not support every WASM.