01 / CLOSED WORLD
Unused means gone.
Only reachable code, data, generics, and imports survive. An unused package reference does not become deployment baggage.
Independent .NET. Built outside Microsoft.
C# with precise GC beats Rust's size-oriented profile for printing 42: 38,919 bytes versus 53,635 bytes. Both are standalone WASI Preview 2 components. NetWasm includes its runtime and reachable precise-GC support.
Live Playground · No account · Your browser does the compiling
C# 15 · 5 development hosts: Linux x64 and ARM64 · macOS ARM64 · Windows x64 and ARM64
FINAL COMPONENT
38,919
bytes
NO CLR.
NO MONO RUNTIME.
NO dotnet.js.
NO APP DLLs.
Measured size
The released SDK produces a 38,919-byte Release/Oz component for Console.WriteLine(42), or 13,213 bytes with Brotli quality 11. Rust 1.95.0's documented size-oriented profile produces 53,635 bytes for the same print-42 workload. This is a measured workload, not a claim about the smallest possible Rust binary.
The qualified Console.WriteLine(42) Release component includes the application, runtime, Compact GC, and WASI component wrapper.
38,919 versus 53,635 uncompressed bytes. Both artifacts print 42 and use WASI Preview 2. Exact toolchain and profile details are published.
Reproduce both builds ↗ 3Compact is the size-first default. NetWasmGC favors throughput; Bump never collects. Objects carry no collector header, so Compact and NetWasmGC use little memory. All use the same SDK selection setting.
Read the latest release notes ↗Speed, measured
NetWasm runs our allocation and garbage-collection benchmarks faster than Mono AOT (.NET 10, wasi-wasm), compiled from the same C# source and run by the same Wasmtime 49.0.3 on an Apple M1 Max. Each figure is the lower median of two 15-run cohorts, and every run is checked against desktop .NET's result. NetWasmGC also takes less time than desktop .NET 11's JIT on all three workloads, and less than desktop NativeAOT on the object graph. Without allocation, NetWasm takes less time than Mono AOT, or matches it, on every workload we publish.
34.8 ms with NetWasmGC versus 59.1 ms for Mono AOT. Strings, a HashSet<int> and decimal balances in a growing dictionary.
4.7 ms versus 14.2 ms to build and keep a graph of 100,000 small objects alive.
Versions and settings ↗ 73%7.8 ms versus 29.1 ms replacing short-lived objects every frame for 500 frames.
Reproduce it ↗NetWasm 0.9
A JsModule project publishes C# [JSExport] methods as a typed JavaScript module. A page imports it, calls open(), and calls the exports directly: synchronously on the page, or behind Promises in a Web Worker. C# calls back into JavaScript, including the DOM, through [JSImport].
Publish writes the module and its .d.mts declarations, named after your C# parameters and nullability. Exports take and return strings, typed arrays, and JSObject.
Set NetWasmJavaScriptHosts to page, worker, or both. The worker host keeps long work off the page's thread behind a generated Promise-based client.
The publish directory is a static site. It needs no cross-origin isolation headers and runs under script-src 'self' blob: 'wasm-unsafe-eval'.
AOT vs AOT
The NetWasm Release/Oz component for Console.WriteLine(42) is 38.0 KiB. The retained .NET 11 RC1 Blazor WebAssembly AOT print-42 build loads 14.58 MiB of Wasm. These are different deployment stacks, not equivalent UI frameworks.
Uncompressed Wasm, excluding JavaScript and the host engine. Binary units: 1 KiB = 1,024 bytes and 1 MiB = 1,024 KiB. NetWasm selects Compact by default. Reproduce the comparison
An independent .NET again
Mono is now part of Microsoft. NetWasm brings back an ambitious .NET implementation built independently, in public, by one developer: compiler, CoreLib, runtime, precise GC, SDK, WASI host, browser toolchain, libraries, and test integration. JetBrains gave Kotlin a portable Wasm platform. This is C#’s answer.
The runtime tax is optional
Roslyn produces CIL. NetWasm compiles the reachable program directly to Wasm, specializes its generics, and links only the runtime support it actually uses. The component is the program.
AOT without the traps
NetWasm works out what your program needs at compile time. JSON, Regex, dependency injection, and structured logging generate ordinary code the compiler can see, so your app does not break because somebody forgot a “do not trim this constructor” annotation three libraries away.
Try the generated-code examplesVISIBLE TO THE COMPILER
✓ Reachability decided at compile time
Smaller by design
NetWasm starts with a smaller platform contract: closed-world compilation, precise GC, and explicit host capabilities. It does not drag desktop assumptions into every deployment.
01 / CLOSED WORLD
Only reachable code, data, generics, and imports survive. An unused package reference does not become deployment baggage.
02 / C# 15
C# 15, generics, exceptions, async, managed memory, and precise garbage collection compile into the final artifact.
03 / WASI
Programs receive the clocks, HTTP, files, and host interfaces you choose, not ambient access to the machine.
04 / BOTH ADDRESS WIDTHS
Ship portable wasm32 WASI Preview 2 Components, or target raw wasm32 and wasm64 core modules for advanced hosts.
Not a toy compiler
Build, run, publish, test, and reuse focused libraries with the commands you already know.
dotnet build·dotnet run·dotnet publish·dotnet test
LINQ and Async LINQ, Memory, Pipelines, Web Encodings, HTTP, Regex, JSON, XML, Hashing, reflection-free dependency injection, Options, and structured logging.
Explore libraries ↗ TRun TUnit through ordinary dotnet test, with source-generated discovery and a NetWasm runner.
Edit C#, compile it locally, run the result, compare optimization settings, and download the component.
Try it now, no install ↗ .*Regex Storm runs locally in your browser from 260 KB of Brotli-compressed Wasm. Test .NET regular expressions, captures, replacements, and splitting without sending patterns or input to a server. The figure excludes JavaScript, HTML, and other page assets.
Open Regex Storm ↗NetWasm tooling is free for personal and non-commercial use, education, open-source projects, and small and medium-sized businesses. Open-source work is free when the project's complete source uses an OSI-approved license and the work is not a paid or proprietary deliverable. Any business with fewer than 250 employees across its affiliates and consolidated annual revenue below US$10 million, other than a government entity, may use NetWasm for commercial development and production builds, then sell, host, deploy, and distribute unlimited generated applications and output. Larger organizations pay for internal commercial use by sponsoring a matching tier on GitHub Sponsors, from US$149 a month for five developers up to US$2,499 a month for unlimited developers. OEM use and compilation services require a separate agreement.
Read the Community License →Local quickstart
Install .NET SDK 10.0.303 or newer, create an app, run it locally, and publish a standalone component. Use the .NET 11 SDK when your source uses C# 15.
Five supported development hosts: Linux x64, Linux ARM64, macOS ARM64, Windows x64, and Windows ARM64. NuGet downloads the pinned host tools, including the native nwc compiler, on first restore and reuses them on later builds. No separate Emscripten, Node.js, Python, Git, LLVM, or Binaryen setup is needed.
$ dotnet new install NetWasm.Templates
$ dotnet new netwasm-app -n HelloNetWasm
$ cd HelloNetWasm
$ dotnet run
42
$ dotnet publish -c Release -o publish/local
Stop reading. Compile something.
The Playground is a multi-file C# 15 IDE that runs entirely in your browser. Build and run projects, link validated WebAssembly .a archives through LibraryImport, publish a JSExport Web Worker, inspect artifacts, and export the project to your computer.
NetWasm is pre-1.0, so its API and ABI can evolve. The current profile deliberately excludes runtime reflection, dynamic, runtime assembly loading, managed threading, general managed file APIs, raw sockets, and subprocesses.