Publish C# as a Web Worker
NetWasm 0.6.0 adds WIT and JSExport worker templates. A published worker gets its own Wasm instance and managed heap, plus a generated JavaScript client whose methods return Promises.
- Use a WIT worker for a portable, language-neutral component contract.
- Use a JSExport worker when JavaScript should call named managed exports directly.
- Send progress notifications, propagate managed failures, and close workers with defined disposal and termination behavior.
The C# Web Workers tutorial takes a project from template to static deployment.
Cross explicit Wasm boundaries
Browser applications can bundle their own JavaScript modules for reachable [JSImport] calls and expose bounded [JSExport] entry points. WIT workers describe a portable application contract.
Static native interop can link supported C APIs from Wasm .a archives. The qualified profile covers common scalar, pointer, by-reference, struct, union, counted-array, UTF-8, SafeHandle input, and callback shapes. Dynamic native loading and a general C++ ABI remain outside this release.
Run more library patterns
Bounded custom-attribute queries now support framework and user-defined attributes without retaining a general runtime metadata database. The compiler requires statically bounded targets and attribute filters, preserving pay-as-you-use output.
A bounded interpreted expression-tree profile adds equality, property access, calls, construction, invocation, conversions, and lambdas. Together these capabilities unblock the core RuleFor(...).Validate(...) patterns used by the NetWasm port of FluentValidation.
NetWasm 0.6.0 also adds the date/time parsing and exception-region fixes needed by System.Formats.Cbor, secure random-number generation, the portable Interlocked family for the single-reactor runtime, and more compatibility APIs.
See failures where they happen
Debug builds can include managed stack traces with portable-PDB source files and line numbers. Release builds omit that instrumentation unless NetWasmManagedStackTrace=true is explicitly selected.
Hosts preserve managed exception classification and available messages even without rich stack traces. dotnet run now propagates guest exit codes and host failures, and unobserved task diagnostics retain the original exception details.
The release also fixes mutable struct aliasing in exception filters, protected loops in exception regions, open generic layouts in validation rules, package metadata conversion, analyzer target selection, and several SDK packaging edges.
Upgrade to 0.6.0
Install the 0.6.0 templates and update NetWasm package references together. The target framework remains netwasm0.1.
$ dotnet new install NetWasm.Templates@0.6.0
$ dotnet restore
$ dotnet publish -c Release
Republish browser deployments so their generated host files match the 0.6.0 component contracts. NetWasm is still pre-1.0; review the support boundary when bringing in a new package.
Free for qualifying small organizations
A non-government organization with fewer than 250 employees across its affiliates and consolidated annual revenue below US$10 million may use NetWasm tooling at no charge for commercial development, production builds, and creating products or services.
Qualifying organizations may sell, license, host, deploy, or distribute unlimited generated applications and output without royalties or additional fees. Commercial redistribution of NetWasm itself, bundling it into an SDK or IDE, or providing compilation through a hosted service requires a separate agreement. See the Community License guide and complete terms.
Personal non-commercial use, education, qualifying open-source work, and contributions to official NetWasm projects are also free. The compiler and developer tooling are source-available under the Community License. CoreLib, runtime components, templates, generated support code, and the focused library ports are MIT licensed unless an upstream notice says otherwise.
Pay-as-you-use remains measurable
The optimized Release Console.WriteLine(42) component is 84,653 bytes (82.7 KiB), uncompressed and including the application, runtime, precise GC, and WASI component wrapper.
That is 140 bytes (+0.17%) above NetWasm 0.5.0's 84,513-byte result. The increase comes from ArgumentNullException.ThrowIfNull preserving the caller-expression parameter name through ParamName and Message, which is observable .NET behavior. Rich stack-trace instrumentation remains absent from this Release artifact.
Qualification covered 2,259 compiler and runtime cases plus package-consumer and host validation. See the reproducible size methodology and the complete release notes.