WitBindgen.Runtime 0.1.3

dotnet add package WitBindgen.Runtime --version 0.1.3
                    
NuGet\Install-Package WitBindgen.Runtime -Version 0.1.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="WitBindgen.Runtime" Version="0.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="WitBindgen.Runtime" Version="0.1.3" />
                    
Directory.Packages.props
<PackageReference Include="WitBindgen.Runtime" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add WitBindgen.Runtime --version 0.1.3
                    
#r "nuget: WitBindgen.Runtime, 0.1.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package WitBindgen.Runtime@0.1.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=WitBindgen.Runtime&version=0.1.3
                    
Install as a Cake Addin
#tool nuget:?package=WitBindgen.Runtime&version=0.1.3
                    
Install as a Cake Tool

wit-bindgen-dotnet

NuGet NuGet CI

C# source generator that produces bindings from WIT (WebAssembly Interface Types) definitions, enabling .NET WebAssembly components using the Component Model.

What it does

wit-bindgen-dotnet reads .wit files at compile time and generates C# code for both sides of the component boundary:

  • Guest side (WitBindgen.SourceGenerator) — generates DllImport stubs for imports and UnmanagedCallersOnly exports, so your .NET code can be compiled to a WASM component via NativeAOT-LLVM.
  • Host side (Wasmtime.SourceGenerator from wasmtime-dotnet) — generates an abstract *Imports class you implement to provide host functions, and a typed *Exports wrapper to call into the guest.

Supported WIT types

WIT type C# mapping
Primitives (u8..u64, s8..s64, f32, f64, bool, char, string) Native C# types
list<T> ReadOnlySpan<T> (imports), arrays (exports)
option<T> T?
result<T, E> Generated result types
record struct with fields
enum C# enum
flags C# [Flags] enum
variant struct with discriminant + payload
resource Abstract class with handle table (host), DllImport stubs (guest)
tuple<...> C# tuples
borrow<T> Handle parameter

Project structure

wit-bindgen-dotnet/
  src/
    WitBindgen.SourceGenerator/   # Guest-side Roslyn source generator
    WitBindgen.Runtime/           # Runtime helpers for guest components
  examples/
    HelloWorld/                   # Minimal guest example
    Calculator/                   # Guest WASM component (NativeAOT-LLVM)
    CalculatorHost/               # Host that loads and runs the calculator
  tests/
    WitBindgen.Tests/             # Parser and code generation tests
  external/
    wasmtime-dotnet/              # Submodule: Wasmtime .NET bindings + host source generator

Prerequisites

  • .NET 10 SDK
  • NativeAOT-LLVM workload (for publishing guest components to WASM)

Building

Clone with submodules:

git clone --recurse-submodules https://github.com/andreakarasho/wit-bindgen-dotnet.git
cd wit-bindgen-dotnet

Build everything:

dotnet build WitBindgen.slnx

Run tests:

dotnet test WitBindgen.slnx

Usage

Writing a guest component

1. Define your WIT world:

// wit/hello.wit
package example:hello@1.0.0;

interface console {
    log: func(message: string);
}

world hello-world {
    import console;
    import get-name: func() -> string;
    export run: func() -> string;
}

2. Create the project:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net10.0</TargetFramework>
        <RuntimeIdentifier>wasi-wasm</RuntimeIdentifier>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
        <PackageReference Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
    </ItemGroup>

    <ItemGroup>
        <PackageReference Include="WitBindgen.SourceGenerator" Version="0.1.0">
            <PrivateAssets>all</PrivateAssets>
            <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
        </PackageReference>
        <PackageReference Include="WitBindgen.Runtime" Version="0.1.0" />
    </ItemGroup>

    <ItemGroup>
        <WasmComponentTypeWit Include="wit\hello.wit" />
    </ItemGroup>
</Project>

The NuGet package sets WASI-WASM defaults (AllowUnsafeBlocks, SelfContained, etc.) automatically. You also need to add the NativeAOT-LLVM compiler packages so the project compiles to .wasm:

<ItemGroup>
    <PackageReference Include="Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
    <PackageReference Include="runtime.$(NETCoreSdkPortableRuntimeIdentifier).Microsoft.DotNet.ILCompiler.LLVM" Version="10.0.0-*" />
</ItemGroup>

3. Implement the exports:

The source generator creates partial classes in the Wit.<Namespace>.<Package> namespace. You implement the exported functions as partial methods:

namespace Wit.Example.Hello;

public static partial class HelloWorld
{
    public static partial string Run()
    {
        // Call imported functions
        var name = Imports.GetName();
        Console.Log($"Hello, {name}!");
        return $"Hello, {name}!";
    }
}

4. Publish to WASM:

dotnet publish -c Release

Writing a host application

1. Create the project referencing Wasmtime and its source generator, with the same WIT file:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net10.0</TargetFramework>
        <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    </PropertyGroup>

    <ItemGroup>
        <ProjectReference Include="path/to/Wasmtime.csproj" />
        <ProjectReference Include="path/to/Wasmtime.SourceGenerator.csproj"
                          OutputItemType="Analyzer"
                          ReferenceOutputAssembly="false" />
    </ItemGroup>

    <ItemGroup>
        <AdditionalFiles Include="path/to/hello.wit" />
    </ItemGroup>
</Project>

2. Implement the imports by subclassing the generated abstract *Imports class:

class HelloImportsImpl : Wit.Example.Hello.HelloWorldImports
{
    public override void Log(string message)
    {
        Console.WriteLine($"[guest] {message}");
    }

    public override string GetName()
    {
        return "World";
    }
}

3. Load and run the component:

using Wasmtime;

using var engine = new Engine();
using var linker = new Linker(engine);
linker.AddWasiP2();

var imports = new HelloImportsImpl();
linker.Define(imports);

var bytes = File.ReadAllBytes("hello.wasm");
using var component = Component.Compile(engine, bytes);
using var store = new Store(engine);
store.AddWasiP2();

var instance = store.GetComponentInstance(component, linker);
var exports = new Wit.Example.Hello.HelloWorldExports(instance, store);

var result = exports.Run();
Console.WriteLine(result); // "Hello, World!"

How it works

                    ┌──────────────┐
                    │  .wit file   │
                    └──────┬───────┘
                           │
              ┌────────────┴────────────┐
              │                         │
   ┌──────────▼──────────┐  ┌──────────▼──────────┐
   │ WitBindgen.Source    │  │ Wasmtime.Source      │
   │ Generator (guest)    │  │ Generator (host)     │
   └──────────┬──────────┘  └──────────┬──────────┘
              │                         │
   ┌──────────▼──────────┐  ┌──────────▼──────────┐
   │  DllImport stubs    │  │  Abstract *Imports   │
   │  + export wrappers  │  │  + typed *Exports    │
   └──────────┬──────────┘  └──────────┬──────────┘
              │                         │
   ┌──────────▼──────────┐  ┌──────────▼──────────┐
   │  NativeAOT-LLVM     │  │  Wasmtime runtime   │
   │  → .wasm component  │  │  → loads .wasm       │
   └─────────────────────┘  └─────────────────────┘

Both generators read the same .wit file and produce complementary code. The guest compiles to a .wasm component that the host loads and runs via Wasmtime.

License

Apache-2.0 WITH LLVM-exception

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net9.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.3 38 2/17/2026
0.1.2 42 2/17/2026
0.1.1 40 2/16/2026
0.1.0 46 2/16/2026
0.0.0-alpha.0.9 42 2/16/2026
0.0.0-alpha.0.7 37 2/16/2026