At the moment, web developers typically use JavaScript (JS) to write the front-end of web applications. Or they resort to a language like TypeScript, which they must compile to JS before a browser can execute it. Unlike TypeScript, JS is a World Wide Web Consortium (W3C) standard along with HTML and CSS.
In December 2019, the W3C standard approved a fourth official language: WebAssembly (Wasm). This one is significantly different from the previous languages regarding structure, use, and capabilities.
Most importantly, Wasm is not a programming language in the traditional sense. Instead, it is a binary format that enables software developers to write web applications in languages of their choice. These languages include C, C++, Rust, C#, or, theoretically, any programming language that includes the necessary tools for compiling source code into Wasm.
However, Wasm is not just about enabling developers to write web applications in their favorite language. It’s also about pioneering a new way to offer high-performance software to end users without extra downloads or installations.
JS developers can write more performant and relatively secure code than was previously feasible. While TypeScript and other comparable superset languages of JS aided in producing safe code had little effect on performance.
Before delving into what WebAssembly is, it’s worth noting that while the name implies an assembly language, it actually provides low-level language-like assembly languages and a binary format supported by modern web browsers. Developers don’t have to write it by hand but can use it as a compilation target for programs written in any preferred language.
Let’s begin with a definition of WebAssembly and a brief history of this technology.
In 2015, Brendan Eich, the creator of JavaScript and co-founder of Mozilla, announced the beginning of cross-browser development on WebAssembly. This technology would eventually be a better alternative for JS as a compiler target. WebAssembly version 1.0 launched in 2017, and the W3C approved it as a standard in 2019.
WebAssembly is a freely available and publicly accessible implementation standard that enables low-level binary code execution on the web. Developers can use this technology (also known as a binary code format) to bring the performance of C, C++, Rust, and similar languages to web programming. This is commonly used in browsers for quick computations.
To put it another way, it’s a file object format that’s both secure and portable. And it executes at the same pace as native code, thanks to the format’s robust optimization. This means that any language that compiles to this format should run in a browser. As the creator of JS stated, this makes WebAssembly a binary format for a Polyglot-programming language for the web.
In compiled languages, such as C, an object file is a file created after the source code finishes compiling. Its primary goal is to provide native-like performance while remaining compatible with the current web development environment.
Thanks to the combined efforts of Google, Microsoft, Mozilla, and a few others, Wasm is now supported by Chrome, Firefox, Safari, and Edge.
When it comes to any software development problem, developers are constantly attempting to find a solution. Concerned about web application performance on browsers, the community created asm.js, a JS subset designed to execute computer software as web apps. This was written in languages such as Rust, with better performance than ordinary JavaScript.
Asm.js is a restricted subset of JS. A compiler, such as Emscripten, converts code written in statically typed languages into Asm.js. The advent of Wasm, which uses a faster parsing and compacting format, has replaced it and efforts to extend JS with further low-level functionality, such as SIMD.js, ended in 2017.
Due to conversion software built by the WebAssembly organization, asm.js remains useful as a fallback for Wasm.
There are two general scenarios where developers might want to use Wasm.
One is as a web developer who wants to write more performant code.
Another is as a software developer who wants to use existing skills with other programming languages (such as C++ or Rust) to build software that runs on the web and reaches users through web browsers without the need for additional steps such as downloading and installing programs.
While developers would still need to use JavaScript in the first scenario, they could also use Wasm to generate the pieces that require near-native speed as modules and load them using JS. This is because the ability to communicate bidirectionally between JS and WebAssembly modules enables apps to take advantage of WebAssembly’s excellent performance.
Developers can continue to use popular UI libraries such as React to build the UI of web apps and use Wasm indirectly for the high-performance internal logic. Popular applications such as Figma adopted this technique by using React and C++.
As Brendan Eich pointed out, the fact that Wasm will eventually enable the compilation of many different languages for the web will not influence JS’s continued dominance. Developers are more likely to combine JS and Wasm in various ways than phase out JS altogether.
For the second scenario, developers can use languages such as Rust, C++, or C# with Blazor to write web applications. Or even design a game in C# and easily compile it to Wasm, then serve it to consumers through the web.
Tools like Emscripten, which generates short and fast code, employ Wasm as an output format. It’s a compiler for WebAssembly using LLVM, emphasizing speed, small size, and web compatibility.
Real-world codebases, including commercial ones like Unreal Engine 4 and Unity, have already used Emscripten to convert their codebases to Wasm.
Developers should use Emscripten with a C or C++ application. For Rust, developers can use wasm-pack.
Games, virtual reality, and augmented reality applications are examples of what developers should create in high-level programming languages and compile to Wasm for optimal performance.
In exceptional circumstances, such as designing special tools like compilers, developers may need to write a whole codebase in Wasm manually.
Briefly, developers can use Wasm in the following ways:
In addition to JS, developers can write performance-critical code in Wasm and import it with JS.
Developers can use Wasm as a compilation target that enables other programming languages to write code that runs on the web.
WebAssembly is not just for browsers. Developers also use it in servers with Node.js, smartphones, and edge-based environments such as Cloudflare Workers.
WebAssembly, as the name implies, is supposed to run on browsers. However, developers can use it both inside and outside of the web.
Wasm can run on browsers and servers with Node.js and virtual machines or Wasm runtimes. Developers can use Wasm runtimes to execute Wasm in a non-web environment using WebAssembly System Interface (WASI).
Its application possibilities in non-web environments range from blockchain as a smart contract runtime to apps running on IoT devices, mobile and desktop apps, servers, or as an executable within large software systems.
For reference, here is a list of WebAssembly runtimes.
WebAssembly supports the text-based WebAssembly format (WAT) and the binary format. While WAT is a textual format that is reasonably simple to read and write, the browser executes its binary format.
Now, what if a web developer wants to write Wasm without resorting to other programming languages like Rust to compile to Wasm? Developers can either write WAT by hand, which requires a high learning curve since it lacks high-level abstractions such as “if statements” and for loops. Or use AssemblyScript, which is an excellent approach to writing code if you are already familiar with TypeScript. This is because AssemblyScript actually resembles TypeScript, allowing developers to work with a more familiar syntax.
Besides using AssemblyScript, there are numerous methods for generating Wasm binary files, such as manually writing WebAssembly and converting it to binary using tools such as wabt.
There are many toolkits available for developing web apps with Wasm. Some examples include Blazor, yew, and Smithy.
Blazor, for one, allows developers to use C# instead of JavaScript to create interactive web user interfaces. Blazor apps are reusable C#, HTML, and CSS web user interface components. Both the client and server code are C#, allowing for the sharing of code and libraries.
Here is a recap of the advantages of WebAssembly:
To summarize, WebAssembly can coexist with the JS engine that drives web browsers.
Developers can compile other high-level programming languages, such as Rust, C, and C++, to Wasm for increased performance thanks to its low-level binary format.
Except in a few circumstances, such as when developing a compiler, developers don’t need to write WebAssembly. Instead, they can use it as a compilation target.
Thanks to Wasm, the web, and primarily its front-end, has become a powerful platform for running all types of high-performance programs, such as 3D games and video processing software. However, this is not to say that WebAssembly will eventually supersede JS for web application development, but it is an excellent tool for optimizing web performance.
If you’re looking for an easy way to start with Wasm, give ComponentOne with Blazor a try.
ComponentOne, Blazor Edition is a set of Blazor UI controls provided by ComponentOne. For details, refer to the demos and documentation.
Also published here.