Mono on WebAssembly status update


Hello there!

As you may have seen in Miguel’s post ( we have been experimenting with porting Mono to WebAssembly, and thought you would like to know what we have so far and where we are heading.

Our current plan is to build a “hybrid” version of Mono for WebAssembly that supports both interpreted and compiled programs. The interpreter mode would be used for development / debugging and the compiled mode would be used for deployment / release.

So far we have an early version of the Mono interpreter working as well as a mono-wasm tool that statically compiles ahead-of-time IL assemblies into WASM code (as well as linking/stripping the IL code), using the experimental LLVM WebAssembly backend and the binaryen tooling.

Currently we are focusing on bringing incremental WASM compilation to the compiler, tuning the garbage collector, customising the mscorlib library, exposing APIs (C# to JS and vice-versa), and a few more things.

The work that we are doing hasn’t converged yet into the Mono repository but as soon as it does we will start releasing builds that you can play with and report feedback about. We are very excited by WebAssembly and hope you will too!


A bit more information about that mono-wasm tool, let’s start with a simple “hello world” program.

$ cat hello.cs 
class Hello
    static int factorial(int n)
        if (n == 0) {
            return 1;
        return n * factorial(n - 1);

    static int Main(string[] args)
        int f = factorial(6);
        System.Console.WriteLine("Hello world! factorial(6) -> {0}", f);
        return f;
$ mcs hello.cs -out:hello.exe

Now let’s pass it to mono-wasm and use output as the output directory where files should be created.

$ rm -f output
$ mono-wasm -g hello.exe -o output -O3
$ ls output
hello.exe	index.js	index.wasm	mscorlib.dll

As you can see a bunch of files have been created in the output directory. Our hello.exe and mscorlib.dll assemblies are there (after a linker pass and stripped from code). index.js contains the JavaScript glue required to launch the code (it’s minified) and of course, index.wasm is the real deal.

Following are the files sizes, don’t pay too much attention to them as they will be greatly reduced in the future once we start customising the mscorlib library.

$ du -h output/*
4.0K	output/hello.exe
 16K	output/index.js
 10M	output/index.wasm
1.1M	output/mscorlib.dll

We can run this using the d8 program (a debug shell for v8):

$ (cd output && d8 --expose-wasm index.js)
mono-wasm: booting main()
mono-wasm: initializing mono runtime
mono-wasm: opening main assembly `hello.exe'
mono-wasm: running Main()
Hello world! factorial(6) -> 720
mono-wasm: terminating mono runtime


This is really cool! I might try to convert my web + server SPA into a purely client-side application :slight_smile:

I’m not sure if it’s related, but have you looked into the C#/Razor/WebAssembly project that the ASP.NET team has been working on?


Hi there!!!
You see this??

How Is related with this??


I use Bridge.NET at work. Its a transpiler not a “normal” compiler. As in it transpiles C# syntax into JS. This Mono-WASM stuff compiles .NET IL into WASM.

Bridge.NET is probably much better if you need to share C# types / methods with JS/TS.
Mono-WASM will probably be much better for full blown .NET web apps/games that silverlight / flash were good for eventually. Just like Mono-NACL was for the game Bastion on Chrome Store.


Wow, nice work guys!

What about interop with native libraries such as SDL? will it be possible?


Also, isn’t this what CoreRT tries to AIM, compilation to native using LLVM, why not use that to also target WebAssembly?


My guess is it will be if the .NET GC also works. I’m a believer in CoreRT to portable ‘C’ over LLVM as it allows for far more options. Such as GCC + Clang targets (kinda like IL2CPP can do). Example would be Risc-V chips which gcc only supports I believe.


Any update?Is the mono-wasm going to be included into xamarin, like Xamarin.Wasm and be viable with forms?


any update ? wish there is some great news


An update has been published here regarding the static compilation strategy we are pursuing:


The update looks cool. However: compilation strategy is listed as static, and description is of compilation strategy for C#. Are all CLR languages going to be supported (VB.NET and F#)? Are DLR languages going to be supported?

.NET Foundation Website | Blog | Projects | Code of Conduct