What languages are supported in WebAssembly outside the browser?


What languages are supported in WebAssembly running outside the browser? This is a question I often hear people ask. It’s has a complicated answer because:

  1. WebAssembly outside the browser needs WASI and not all languages have WASI support in their toolchain.
  2. Even if WASI is supported well in a language, WASI has its own limitations that you need to take into account.

In short, you can’t take any code written in any language and expect to compile and run it as a Wasm+Wasi module right now. Documentation on what’s supported is patchy or misleading at times. Unfortunately, you often need to try things out before knowing what works and what doesn’t.

Let’s take a look in more detail.

Resources on language support

I found 2 resources to understand the language support in Wasm+Wasi.

First one is WebAssembly Support in Top 20 Languagess from Fermyon:

WebAssembly Support in Top 20 Languages

Second one is the WebAssembly Introduction page from Enarx:

WebAssembly Introduction

Both are good resources to understand the level of support in each language but they should be taken with a grain of salt.

For example, both resources agree that Rust, C, C++, Go have good Wasm+Wasi support whereas .NET, Java has experimental support. On the other hand, they don’t seem to agree on JavaScript support. Fermyon says JavaScript doesn’t have WASI support whereas Enarx thinks it has experimental support.

“Excellent” support languages

Rust, C, C++, Go are supposed to have excellent Wasm+Wasi support but what does excellent mean in this case?

Almost all of the Wasm+Wasi tutorials show Rust because it’s trivial to take a Rust application and compile it to Wasm+Wasi (I show it in this sample) with the regular Rust tooling. However, you have to keep in mind the WASI limitations. In WASI, there’s no threading or socket support which translates to no Tokio or async support in Rust.

Similarly, in C/C++, you can’t have C++ exceptions or threads. Go is supported by TinyGo (and more recently with Go 1.21 RC) but no reflection features of Go are supported in WASI.

As you see, some of the basic features you take for granted in languages are not yet supported due to WASI limitations. Excellent support in this case is a little misleading. It basically means you can compile a WASI limited code using the standard tools of the language but not full language support.

Experimental support languages

In experimental support languages, the situation is even more complicated.

For example, Java is supposed to have some WASI support via fork of TeaVM (a Java to Javascript compiler) but good luck trying to get that working (I gave up after some time).

Kotlin has some WASI support (see here for an example) via kowasm that relies on the Node experimental WASI API. So, you need Node to run Kotlin? Yuck!

In .NET, there was a Wasi SDK for .NET 7 to compile .NET apps to WASI but it got replaced by wasi-experimental workload in .NET 8 preview (see a demo video here). It feels like the .NET team wants to support Wasm+Wasi but the tools are changing from release to release.

What about JavaScript? Shopify has Javy: A JavaScript to WebAssembly toolchain. It seems to have WASI support which in turn should mean that you can compile Javascript to WASI but I haven’t tried it myself. There might be other ways but I didn’t investigate further.

Conclusion

As you can see, the language support in Wasm+Wasi is still in its infancy and changing all the time. Right now, it’s not so easy to understand what parts of a language works in a Wasm+Wasi setup without actually trying it out but hopefully, this will get better as WASI and languages mature. In the meantime, I update my wasm-basics repo, as I work on samples in different languages.


See also