.NET Software Engineering

.NET 7 Feature Breakdown Of The WebAssembly Build Tool


November 29, 2022



The .NET WebAssembly build tool is used to compile .NET code to WebAssembly (WASM) and other runtime features. This blog will take you through the different features with the .NET WebAssembly build tool and new features to help you build performant, powerful .NET apps using WASM. It is based on Emscripten, it compiles languages that use LLVM (low level virtual machine), into WebAssembly. 

At the time of writing this document, there are 3 different versions:

1. wasm-tools: Used for Ahead-of-time compilation, runtime relinking etc.

2. wasm-tools-net6: Addressing incompatibility issues for .NET 6 projects running on .NET 7 SDK

3. wasm-experimental: Multithreading and calling Javascript from .NET applications and vice versa.

It can be installed by running the relevant command in a terminal:

Ahead-of-time compilation

Even though Ahead-of-time (AOT) compilation is an existing feature in .NET 6, I feel it is still worth mentioning.  Enabling this feature will compile .NET code to WASM and result in runtime performance improvement.

To enable add RunAOTCompilation property and set the value to true in the project file:

Publishing the app with the Release configuration ensures that .NET Intermediate Language linking runs to reduce the size of the published app.

WebAssembly Single Instruction Multiple Data (SIMD)

WebAssembly Single Instruction Multiple Data (SIMD) is available when a project enables AOT.  It is a new feature in .NET 7, for developers who develop applications with compute-intensive needs i.e. gaming, image processing etc.  SIMD is a technique to speed up calculations.  It works on multiple data within a single CPU instruction where multithreading works on multiple data in different threads. This blog by Rober Aboukhalil has more detailed information.

SIMD is supported when AOT is enabled (except for in the Apple Safari browser). To enable this feature add the WasmEnableSIMD property and set the value to true in the project file: 

Runtime relinking

The dotnet.wasm .NET runtime must be downloaded when the user accesses the app for the first time. This feature reduces the size of the dotnet.wasm file by trimming unused runtime code. It happens automatically when the app is published in Release config. By disabling globalization in the project, the reduction is even more exorbitant.  Runtime relinking was introduced in .NET 6.

Experimental WASM workload

The wasm-experimental workload introduces a new low-level mechanism for using JavaScript in .NET apps and vise versa and WebAssembly multithreading.  

.NET Javascript interop on WebAssembly

With this new JS interop capability we can invoke .NET code from Javascript or vice versa without any dependency on the Blazor UI component model.

Create a new WebAssembly Browser App template by running: 

Two experimental project templates are available after installing the experimental workload: 

- WebAssembly Browser App

- WebAssembly Console App

JS calling .NET and visa versa

The following section is an overview of this feature.

JavaScript apps using .NET

dotnet.js contains APIs that enables named modules to be created and then imported into C# code.  These modules then call into methods exposed by your .NET app.  

The dotnet.js library is required and needs to be imported into the javascript file.

Setup the .NET WebAssembly runtime:

A module that can be called from .NET by using setModuleImports is required. The first parameter is the module name (main.js) and the second parameter is the name of the method.

Setup the .NET WebAssembly runtime in JS and run the program

.NET apps using JavaScript

To call the Javascript module from C# we can use the new JSImport Attribute. The first parameter is the name of the JS function, and the second parameter is the name of the module :

The JSExport attribute exports a .NET method and can be imported into JS.  In C# decorate a method with JSExport attribute.

❗If you get the following error when running the application:

You need to follow the instructions set out in the Readme.md file that is created when creating the app.

This is what you will see in the browser when you run the above code: 

There is a fantastic detailed Microsoft devblog from Pavel Savara around this topic.

It is inspiring to see these new inventions and I am excited about the possibilities these features create.


Next Article

Looking for a new challenge?

We’ve got ambitious plans to be the best Microsoft solutions company in Australia and New Zealand.