What Languages Support WebAssembly?

Updated Aug 17, 2021#webdev#wasm#lists

WebAssembly (abbreviated Wasm) is the next big thing when it open the gate the web platform to all high-level programming languages beside the exclusive JavaScript.

So currently which languages can be compiled to WebAssembly? Language conformance is largely determined by individual compiler support, there have been around 40 programming languages reported to support Wasm as a compilation target.

You can find all languages and tools that work with WebAssembly here. Notable languages are C/C++, C#/.NET, Rust, Java, Python, Elixir, Go. Take a took at several tools/frameworks related to WebAssembly:

  • Blazor - A .NET web framework using C#/Razor and HTML that runs in the browser with WebAssembly.

  • JWebAssembly - Java bytecode to WebAssembly compiler. It uses Java class files as input. That it can compile any language that compile to Java bytecode like Clojure, Groovy, JRuby, Jython, Kotlin and Scala. As output it generates the binary format (.wasm file) or the text format (.wat file). The target is to run Java natively in the browser with WebAssembly.

  • Pyodide - Python scientific stack brings the Python runtime to the browser via WebAssembly, along with the Python scientific stack including NumPy, Pandas, Matplotlib, parts of SciPy, and NetworkX.

  • ElixirScript - A compiler to convert a subset (or full set) of Elixir code to JavaScript, providing the ability to write JavaScript in Elixir. This is done by taking the Elixir AST and converting it into JavaScript AST and then to JavaScript code. This is done using the Elixir-ESTree library.

  • Yew - A modern Rust framework for creating multi-threaded front-end web apps with WebAssembly. It features a component-based framework, has great performance by minimizing DOM API calls, and supports JavaScript interoperability.

WebAssembly support seems pretty early days and often self-labeled as experimental, I am hoping that the community continues to investigate and embrace WebAssembly.

What is WebAssembly?

In a nutshell, WebAssembly is a low-level assembly-like near-native performance language that can be run in modern web browsers, designed as a portable target for compilation of high-level languages like C++ or Rust, and plays nicely with other technologies in the web platform.

Relative to Javascript, WebAssembly offers predictable performance. It is not inherently faster than Javascript, but it can be faster than JavaScript in the correct use cases such as computationally intensive tasks, like nested loops or handling large amounts of data. Therefore, WebAssembly is a compliment to JavaScript, and not a replacement.

WebAssembly runs on all major web browsers, V8 runtimes like Node.js, and independent Wasm runtimes like Wasmer.

WebAssembly has Linear Memory, in other words, one big expandable array. And in the context of Javascript, synchronously accessible by Javascript and Wasm.

WebAssembly can export functions and constants, And in the context of Javascript, synchronously accessible by Javascript and Wasm.

Why was WebAssembly created?

It’s all about performance! JavaScript is a high-level programming language which makes it hard to achieve near-native performance like C/C++ which is important in cases of porting video games, video editing, 3D rendering to web apps.

Porting desktop apps to web is tempting because decrease the time to customers, no download and installation needed, sharing in the web is easy, just one step away from search results to awesome apps.

WebAssembly was created as a complement to current web platform, can communicate with JavaScript, has text-based format for developer and binary format to promote other compilers and tools targeting WebAssembly.

Even WebAssembly is designed to run on the web initially, it is also desirable for it to be able to execute well in other constraint environments like mobile and IoT devices.

WebAssembly will, over time, allow many languages to be compiled to the Web ultimately; developing web apps will be more powerful and productive when we can write in high-level non-JavaScript languages like Python, C++, Dart as long as they are compiled to WebAssembly.

How hard could it be WebAssembly?

WebAssembly encodes a low-level, assembly-like programming language. This language is structured around the following concepts:

  • Values: WebAssembly provides only four basic value types. These are integers and IEEE 754-2019 numbers, each in 32 and 64 bit width.
  • Instructions: The computational model of WebAssembly is based on a stack machine. Code consists of sequences of instructions that are executed in order.
  • Traps: Under some conditions, certain instructions may produce a trap, which immediately aborts execution.
  • Functions: Code is organized into separate functions. Each function takes a sequence of values as parameters and returns a sequence of values as results.
  • Tables: A table is an array of opaque values of a particular element type. It allows programs to select such values indirectly through a dynamic index operand.
  • Linear Memory: A linear memory is a contiguous, mutable array of raw bytes. Such a memory is created with an initial size but can be grown dynamically.
  • Modules: A WebAssembly binary takes the form of a module that contains definitions for functions, tables, and linear memories, as well as mutable or immutable global variables.
  • Embedder: A WebAssembly implementation will typically be embedded into a host environment. This environment defines how loading of modules is initiated, how imports are provided (including host-side definitions), and how exports can be accessed.

How can I use WebAssembly now?

So far, WebAssembly has been used for all sorts of applications, ranging from gaming (e.g. Doom 3), to porting desktop applications to the web (e.g. Autocad and Figma). It is even used outside the browser, for example as an efficient and flexible language for serverless computing.

Firefox and Chrome browsers currently support the wasm format on Linux, MacOS, Windows and Android. The latest versions of Edge and Safari now include WebAssembly support as well.

The WebAssembly ecosystem is at a early stage, more tools will undoubtedly emerge going forward. Currently there are four main entry points:

  • Porting a C/C++ application with Emscripten.
  • Writing or generating WebAssembly directly at the assembly level.
  • Writing a Rust application and targeting WebAssembly as its output.
  • Using AssemblyScript which looks similar to TypeScript and compiles to WebAssembly binary.

How does WebAssembly code look like?

Here is an example function illustrated in C++:

// C/C++
int factorial(int n) {
  if (n == 0)
    return 1;
  else
    return n * factorial(n-1);
}

Equivalent in WebAssembly binary format:

20 00
42 00
51
04 7e
42 01
05
20 00
20 00
42 01
7d
10 00
7e
0b

Equivalent in WebAssembly text format:

get_local 0
i64.const 0
i64.eq
if i64
    i64.const 1
else
    get_local 0
    get_local 0
    i64.const 1
    i64.sub
    call 0
    i64.mul
end

Conclusion

WebAssembly will play an important role in the web platform for coming years, open so many possibilities to enhance web performance, publishing libraries in binary format, writing web apps in multiple programming languages alongside JavaScript, and can become an universal compilation target even outside the web.