返回资讯中心
外部精选
软件工程
#社区热议

C# now beats Rust on WASM size

Independent .NET for WebAssembly and WASI.

Hacker Newssumnole2026/10/21 · 6 天前20 分钟阅读

以下正文同步自 Hacker News,版权归原站所有,已转换为易读排版。

Independent .NET for WebAssembly and WASI.

Write C#. Deploy small, standalone Wasm.

NetWasm is an independent compiler, CoreLib, runtime and SDK that compiles C# and .NET CIL directly to WebAssembly. It does not carry the desktop CLR, Mono, dotnet.js or application DLLs into production.

Compile C# to WebAssembly · Try it in the browser · Install and build · See supported APIs · Read the documentation

NetWasm 0.8.0 + precise GC: 47,798 bytes

Rust 1.95.0 size-oriented profile: 53,635 bytes

For the same print-42 workload, NetWasm's result includes the runtime and precise Compact garbage collector. Both artifacts are standalone WASI Preview 2 Components built with size-oriented settings.

10.9% smaller raw. 20.4% smaller with Brotli-11.

Rust is the headline comparison because it uses the same workload and output form. Kotlin/Wasm and TinyGo show the broader footprint landscape, but their targets and runtime boundaries differ. This is a measured workload/profile result, not a language-wide size ranking.

Exact sources, versions, settings and reproduction steps

As of 0.10.0, NetWasm runs our allocation and garbage-collection benchmarks faster than Mono AOT, compiled from the same C# source and run by the same Wasmtime:

These are medians of 15 runs on an Apple M1 Max under Wasmtime 49.0.3, each run checked against desktop .NET's result. Mono AOT is Microsoft's wasi-wasm target in its default Release configuration. NetWasmGC also takes less time than desktop .NET 11's JIT on the first two workloads (49.9 and 9.7 ms); the JIT is faster on UI churn (8.6 ms), and desktop NativeAOT is the fastest on all three.

Versions, settings, desktop figures and reproduction

The 46.7 KiB program is the baseline, not the boundary.

C# 15 · JavaScript modules and Web Workers · static .a interop · WIT/WASI P2 · expression trees · HTTP/JSON/XML/Regex · reflection-free DI · TUnit/VSTest · wasm64 · four allocation strategies

The profile is deliberately smaller than desktop .NET. It already supports complete applications, portable libraries, test projects and browser modules.

Install .NET SDK 10.0.303 or newer, then run:

dotnet new install NetWasm.Templates dotnet new netwasm-app -n HelloNetWasm cd HelloNetWasm dotnet restore dotnet run dotnet publish -c Release -o publish/local

Run the published component with a compatible WASI Preview 2 host, such as Wasmtime:

wasmtime run publish/local/HelloNetWasm.wasm

42

The published component is self-contained with respect to .NET. A WebAssembly host is still required. Build with .NET; run without .NET.

Projects using C# 15 select the .NET 11 SDK; earlier language versions can stay on .NET 10. The SDK restores its pinned Node, LLD and Binaryen tools through NuGet, so an ordinary app does not require a separate Emscripten, Git or Python installation. See the complete quickstart for host, restore, Windows, browser and dual-targeting details.

Roslyn produces CIL. NetWasm compiles the reachable program directly to Wasm, specializes its generics and links only the runtime support it needs. The linked Wasm component is the program.

This is a new .NET platform, not desktop .NET squeezed into a Wasm sandbox. That boundary is what makes native-Wasm-sized C# possible.

How JSON and optional features affect size

Compact is the default: a size-first, precise, non-moving mark-and-sweep collector. It traces compiler-published roots and reference layouts without conservative scanning. Its name refers to implementation size, not moving heap compaction.

Select a strategy in the executable project's .csproj:

<PropertyGroup> <NetWasmGarbageCollector>NetWasm</NetWasmGarbageCollector> </PropertyGroup>

Leaving the property unset selects Compact. Libraries remain collector-neutral; all four backends are packaged for wasm32 and wasm64. See Choosing a garbage collector for the tradeoffs and diagnostics.

A library written for the smaller NetWasm profile should also be useful on desktop .NET, rather than trapped in a Wasm-only ecosystem.

dotnet new netwasm-lib -n MyLibrary

The template targets netwasm0.1 and net10.0, producing NuGet assets for both platforms. This is explicit multi-targeting, not a promise that arbitrary desktop packages work in reverse.

NetWasm.Libraries provides the ported framework and extensions packages. TUnit-NetWasm provides ordinary dotnet test integration through the generic VSTest bridge.

For an empty-UI Blazor WebAssembly application that prints 42, with AOT, managed trimming, IL stripping, invariant globalization and size-focused native linking enabled:

The Blazor total includes its native runtime and required Webcil assemblies; NetWasm includes its runtime, garbage collector and WASI component. This is a console component versus an empty-UI application, not an equivalent-framework comparison or a claim about every .NET workload.

Exact Blazor versions, settings and reproduction

NetWasm is pre-1.0. Its supported profile is usable today and covered by published qualification, but source, package, target-profile and ABI contracts may change between minor releases.

The normal portable output is a wasm32 WASI Preview 2 Component. Raw wasm32, raw wasm64 and JavaScript-host integration are advanced alternatives; wasm64 Components remain blocked by upstream tooling.

Runtime reflection, dynamic, runtime assembly loading and managed threading are outside the profile. General System.IO.File/Directory/FileStream, raw sockets and subprocess APIs are not yet implemented. Existing NuGet packages work only when their reachable code and API dependencies fit the supported profile.

Supported APIs and limitations · Documentation index

NetWasm 1.0 means a useful, documented and stable smaller platform. It does not mean “desktop .NET, but in Wasm.” The main remaining themes are:

New in NetWasm 0.10.0: rebuilt garbage collectors. Objects carry no collector header, arrays are single allocations, NetWasmGC allocates by advancing a pointer, and Compact has a new core built for size and memory. Allocation-heavy programs run faster and use far less memory, and applications that ship time zone data start in a fraction of the time. The Boehm collector is removed. Release notes

In progress: broader compatibility with existing .NET Standard 2.1 library binaries and NuGet assets. The target is to consume libraries unchanged when their reachable code fits the NetWasm profile, without carrying unused unsupported paths into the application.

This does not turn NetWasm into desktop .NET. Reachable general runtime reflection, dynamic, runtime assembly loading, managed threading, unsupported host APIs and named-culture globalization remain outside the initial compatibility slice and fail at compile time.

Compiler, SDK, runtime and hosting packages NetWasm.Compiler.Browser · NetWasm.Compiler.Tasks · NetWasm.Hosting · NetWasm.Hosting.Build · NetWasm.Ref · NetWasm.Runtime.Pack · NetWasm.Runtime.Wasm32 · NetWasm.Runtime.Wasm64 · NetWasm.Sdk · NetWasm.Templates · NetWasm.Testing.VSTest · NetWasm.Toolchain · NetWasm.Wit.Bindings.Tool

CoreLib, runtime libraries, templates and generated support code are MIT, subject to preserved upstream notices. The compiler and developer tooling use the NetWasm Community License 1.0. The Compact and NetWasmGC collectors are Apache-2.0.

The Community License is free for qualifying individuals, education, open-source work, evaluation, and organizations with fewer than 250 employees and less than USD 10,000,000 in annual revenue. Matching GitHub Sponsors tiers grant limited internal commercial use; OEM and Commercial Offering use require a separate agreement. Generated applications may use their authors' chosen licenses. There is no sign-in, activation, telemetry or technical enforcement.

Licensing guide · Third-party notices · Commercial licensing: zionsatidev@gmail.com

Start with Console.WriteLine(42), then try the smallest real workload where deployment size, sandboxing or portability matters. If something is missing, open an issue. Concrete workloads are how the 1.0 support boundary gets decided.

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →