Max Desiatov
Max DesiatovI'm Max Desiatov, a software consultant building mobile and backend apps. I curate @ServerSideSwift feed, and co-maintain WebAssembly support for Swift and a framework called Tokamak compatible with SwiftUI.

How WebAssembly changes software distribution

09 September, 2020

If you had any experience with Windows and Internet Explorer in the 90s, quite probably you remember ActiveX controls. Most frequently this involved bulky popups on pages with these controls having to display something more complex than a few blocks of text.

Internet Explorer displaying an alert that requires ActiveX controls to be installed

Or, remember Java applets? They became available in 1995, and later they weren’t limited to just Windows and Internet Explorer. I remember I had to use Java applets on macOS as recently as 2013, which chronologically is closer to the present time than the 90s are. (Feeling so old anyway! 👴)

Microsoft's Application and Network Access Portal that displays a warning about user's browser not
allowing Java applets to run

Seems like ActiveX and Java applets were necessities mostly in the enterprise world, but Macromedia Flash (later known as Adobe Flash) was certainly much more widely known to consumers. It was a requirement in the early days of streaming video (even YouTube required Flash to work back then!), but also a major driver in browser gaming in late 2000s and early 2010s. We certainly could blame Flash for making our browser windows look like this:

Browser page warning about Adobe Flash Player not being installed

While ActiveX has seemingly failed to reach a significant adoption, Microsoft made yet another attempt with Silverlight:

Microsoft Silverlight page with an installation button

In the meantime, Google was working on its own thing for Chrome:

Google Native Client plug-in settings in the Chrome browser

It would be fair to say that these attempts failed to establish wide adoption, especially after both consumers and businesses started shifting to mobile. Here’s how all these forays ended according to Wikipedia:

Microsoft dropped ActiveX support from the Windows Store edition of Internet Explorer 10 in Windows 8. In 2015 Microsoft released Microsoft Edge, the replacement for Internet Explorer with no support for ActiveX, this marked the end of the technology in Microsoft’s web browser development.

“ActiveX” article on Wikipedia.

Beginning in 2013, major web browsers began to phase out support for the underlying technology applets used to run, with applets becoming completely unable to be run by 2015–2017. Java applets were deprecated since Java 9 in 2017 and removed from Java SE 11 (18.9), released in September 2018.

“Java applet” article on Wikipedia.

In July 2017, Adobe announced that it would declare Flash to be end-of-life at the end of 2020, and will cease support, distribution, and security updates for Flash Player.

“Adobe Flash” article on Wikipedia.

There is no Silverlight plugin available for Microsoft Edge. It has not been supported by Google Chrome since September 2015 or by Firefox since March 2017.

“Microsoft Silverlight” article on Wikipedia.

On October 12, 2016, a comment on the Chromium issue tracker indicated that Google’s Pepper and Native Client teams had been destaffed.

“Google Native Client” article on Wikipedia.

But JavaScript solved all these problems, didn’t it?

Most of these browser add-ons were introduced before modern JavaScript and HTML5 became available, so one could argue you no longer need browser add-ons at all. Well, some purists even say browsers should have never supported JavaScript or any scripting whatsoever in the first place. Nevertheless, there are enough use cases for browser scripting and browser apps in general that are hard to avoid. When looking at the history of browser plugins in general, it’s hard not to notice a few themes:

  • Distributing productivity apps via browsers is convenient in a lot of cases.
  • Browser gaming made a lot of sense, especially for casual games.
  • In both of these scenarios browsers had to display something more complex than text and a few static images.

Flash Element TD game screenshot with a classic tower defense battle field

The modern casual tower defense game genre arguably was reborn due to the popularity of Adobe Flash and browser gaming, with Flash Element TD being a classic example.

Even though native apps were (and in many situations still are) objectively better for users, early browser apps were attempting to build their own ad-hoc app stores before the App Store existed. You didn’t have to buy a CD with an application and install it and manage it on your disk. You didn’t have to install updates manually and migrate your data. There was no need to uninstall apps, you just close a corresponding browser tab and forget about it.

And when browser scripting capabilities became advanced enough, some people started seeing the allure of making a browser version of their app the only version they provided. Browsers are cross-platform, aren’t they? Just wrap your JavaScript app code in a browser-like container (say Electron) and distribute that instead of your native app.

But eventually not only the JavaScript APIs became more complex, the language itself could no longer accommodate what developers wanted. Not everyone liked JavaScript syntax (remember CoffeeScript?) or semantics (I couldn’t help but notice that TypeScript has grown in popularity in recent years). But it’s hard to transpile an arbitrary programming language to JavaScript, the latter was not built with that goal in mind.

Corollary, the JavaScript interpreter itself has both memory and performance overhead. Having a garbage collector built in makes it even harder to transpile languages with different memory models to JavaScript. The allure of having only one language to write all your apps for all platforms is still there, but why do you have to be confined to JavaScript itself, even as a target language?

How WebAssembly actually started

With the death of browser plugins, at least we can praise the interoperability efforts of browser vendors. Some lowest common denominator of JavaScript is supported in all browsers, and there is a clear incentive for the vendors to keep up. With the demand to go beyond JavaScript, there were initial attempts to support low level programming with asm.js in 2013:

Much of this performance gain over normal JavaScript [with asm.js was] due to 100% type consistency and virtually no garbage collection (memory is manually managed in a large typed array).

“asm.js” article on Wikipedia.

Syntactically this still looked pretty much like JavaScript, but when you have a lot of low level code, the resulting file can get big pretty quickly, and the size of your code is pretty important when your users download it frequently. As you weren’t supposed to write asm.js code manually most of the time, and it was designed primarily as compilation target, it made sense to invent a binary format for it. That’s basically how WebAssembly started:

WebAssembly was first announced in 2015, and the first demonstration was executing Unity’s Angry Bots in Firefox, Google Chrome, and Microsoft Edge. The precursor technologies were asm.js from Mozilla and Google Native Client, and the initial implementation was based on the feature set of asm.js.

“WebAssembly” article on Wikipedia.

Angry Bots is a 3rd-person shooter demo that features a marine-like character that walks
through some futuristic research base and defends from suicidal four-legged robots

Angry Bots is still available to play on the Unity website.

What WebAssembly got right

Now you’re no longer restricted to JavaScript as a target language for browser apps. As soon as LLVM got WebAssembly backend more or less ready, it allowed compilers built on top of LLVM (for C, C++, Rust, Swift and many more) to adopt it without rewriting everything from scratch. This unlocked the browser environment to a huge amount of pre-existing software that can also run close to native speed if optimized well.

Not only can you run fun little projects such as Sandspiel and in your browser tab, but complex games such as Doom 3 (at least its demo version) are available too. Both Unity and Unreal Engine announced their support for WebAssembly, and while we may not see AAA games running in browsers on their initial release date, this still gives enough confidence in the maturity of the platform.

A pixel-art spherical fish tank filled with water, sand, algae, daphnia and fish.

According to its creator, is “a virtual ecosystem where different species of creature can live, grow and die as part of a self-contained food chain”.

It’s obviously not limited to games, as we can see Apple folks compiling their C++ and Objective-C code from iWork to Wasm1, or 1Password using it in their browser extension getting substantial performance improvements as a result:

With our move to WebAssembly, page filling and analysis now runs at least twice as fast as before, and those websites with a large number of fields are up to 13x faster in Chrome and up to 39x faster in Firefox! It’s blazing fast. 🔥

“1Password X: May 2019 update” article on the 1Password blog.

Wasm is a general purpose virtual machine

Not only you get performance improvements with WebAssembly compared to JavaScript, as it was designed to run arbitrary code in your browser, it’s one of the most widely available secure sandbox environments. And as a general purpose virtual machine, Wasm is not limited only to browsers. Cloudflare uses it for edge computing on their CDN:

We’re excited by the possibilities that WebAssembly opens up. Perhaps, by integrating with Cloudflare Spectrum, we could allow existing C/C++ server code to handle arbitrary TCP and UDP protocols on the edge, like a sort of massively-distributed inetd. Perhaps game servers could reduce latency by running on Cloudflare, as close to the player as possible. Maybe, with the help of some GPUs and OpenGL bindings, you could do 3D rendering and real-time streaming directly from the edge.

“WebAssembly on Cloudflare Workers” on the Cloudflare blog.

With people realizing the wide applicability of the Wasm tech stack, it was no surprise when WASI (stands for WebAssembly System Interface) appeared. Where WebAssembly itself is a “bare metal” platform, it does not supply any primitives such as memory allocation or filesystem access, which WASI does provide. As Solomon Hykes, creator of Docker, puts it:

If WASM+WASI existed in 2008, we wouldn’t have needed to created Docker. That’s how important it is. Webassembly on the server is the future of computing. A standardized system interface was the missing link. Let’s hope WASI is up to the task!

@solomonstre on 27 March 2019.

Many of you may know that shipping compilers or virtual machines through the iOS App Store is prohibited. With Wasm you get the ultimate JIT compiler and virtual machine installed on any relatively recent iOS device. Unsurprisingly enough, people have been able to ship a C++ compiler and a command line shell in an app approved for App Store, so let’s hope this remains a legit way to distribute developer tools on iOS. 🤞

a-Shell and Textastic running side-by-side demoing a

a-Shell and Textastic are available on the iOS App Store.

And what completely blew my mind recently is a JIT compiler for x86 binary code running in browsers (not all browsers yet, it requires some features that are currently only supported in Chrome):

As part of CheerpX, we have implemented a fast x86 interpreter and JIT compiler that can generate WebAssembly modules on the fly to efficiently execute arbitrary x86 applications and libraries, fully client-side.

“Extreme WebAssembly 1: pushing browsers to their absolute limits” on Leaning Technologies’ Blog.

WebAssembly as a platform

As a secure and fast sandbox, Wasm also seems to be a good fit for application plugins. One could imagine editors such as VSCode or Atom allowing extensions to be written not only in JavaScript, but in any language that can target WebAssembly. This would make their extensions ecosystem richer and unlock performance improvements that this platform provides. Miguel de Icaza, the creator of Mono and Xamarin agrees, and goes further with this idea:

[…] IDEs/Editors/Tools could leverage WebAssembly to host their favorite language for scripting during the development stage, but for the final build of a product (like Unity, Godot, Rhino3D, Unreal Engine and really any other application that offers scripting capabilities) they could bundle the native code without having to take a WebAssembly dependency.

“Scripting Applications with WebAssembly” on Miguel de Icaza’s Blog.

WebAssembly is arguably a more direct path towards achieving the idealistic goal of “write once, run anywhere” than Java/JVM ever was. This is thanks to the open nature of the whole stack, potential developer mind share (spanning big and diverse set of languages and ecosystems), and direct involvement of browser vendors such as Apple, Google, Mozilla and Microsoft. This is the opposite to the fractured ecosystem we saw in the 90s and 00s, where every vendor had their own special plugin and forced you to use a specific programming language as a gatekeeping measure.

What WebAssembly still needs

As with any tech stack in its early years, not everything is hunky-dory in the WebAssembly land. It would be unfair if I didn’t mention that debugging with print statements is still a thing when targeting Wasm, or that multi-threading support is not available in all browsers and formally haven’t reached the implementation stage yet. The lack of stable ABI for dynamic linking is not critical and static linking makes some things somewhat easier, but it can still bite at times.

The fact that the vast majority of consumer computing devices (92% as of September 2020 according to have a universal virtual machine that can be targeted by virtually any programming language is still fascinating to me. What WebAssembly definitely needs is more attention from developers, and if all goes well, in a few years we’ll see even more products that weren’t possible before.

  1. Wasm is an abbreviation, but not an acronym, and it is the capitalization that WebAssembly spec authors use (in addition to the all-lowercase “wasm”). Thus, we should follow the authors with this capitalization variant, unless you’re one of those, who writes “IOS”, “XCode” or “IPhone”. 🙈

If you enjoyed this article, please consider becoming a sponsor. My goal is to produce content like this and to work on open-source projects full time, every single contribution brings me closer to it! This also benefits you as a reader and as a user of my open-source projects, ensuring that my blog and projects are constantly maintained and improved.