TypeScript is the bridge between JavaScript and WebAssembly

JavaScript, TypeScript and WebAssembly

WebAssembly is a technology that enables writing browser apps that are packaged to a binary format. These binaries are sent over wire to the browser and executed in a runtime, much like JavaScript. A key difference is that devs won't write WebAssembly by hand — they will do so in a myriad of languages.

Writing WebAssembly requires a strongly type language, which is why C, C++, Java and Rust can be used to write programs that compile to WebAssembly. So, JavaScript's heyday as the only browser language is over, but most web developers are used to writing JavaScript, and learning a new syntax just to get access to WebAssembly is not (always) ideal. If only there was something in to bridge the gap…

This is where TypeScript seems like the perfect go-between. The language syntax is an extension of ECMAScript, the official JavaScript specification. TypeScript builds on standard ES6+ syntax and adds typing, future JS features and other language features there. Valid JavaScript is valid TypeScript.

The TypeScript language, type checker and other infrastructure enables developers to write typed familiar JavaScript syntax that is suitable for compiling to WebAssembly files. The use cases for WebAssembly are (currently) not mainstream, but performance optimizations like WebAssembly Streaming Compilation could benefit common web apps like Progressive Web Applications (PWA).

WebAssembly is coming (and ya probably ain't gonna write it)

WebAssembly is moving forward in key areas like specifications, implementations and devtooling. The infrastructure starts to be in good shape. The core, JavaScript interop (including module imports) are being worked on. It's safe to say that WebAssembly will gain (niche) adoption in the web app space.

The web development tooling in general has undergone a huge transformation in the last five years. Packet management with NPM and transpiling code to with Babel, ClojureScript, CoffeeScript, TypeScript, etc. are a staple task in 2018. Reusing these skills for WebAssembly would be ideal.

Similar to modern JS development, WebAssembly will also compile a transpilation phase. In the case for Babel/TypeScript the target won't be downcompiling to a JavaScript version supported by majority of browsers, but rather the wasm format, the file format consumed by WebAssembly virtual machines.

Before WebAssembly/Wasm there was a technology called asm.js, this was a very limited version of JavaScript. Even with this approach compiling C and C++ apps to run in browsers using a standard JS engine like V8 or Chakra. The common tool for compiling asm.js was (and is) known as emscripten.

WebAssembly, and asm.js before it, focuses on areas not common to web developers. You'll likely consume a lot of WebAssembly in the form of libraries to do things like image and video compression for sure. It was a similar situation with jQuery: Everybody used it, but a handful developed jQuery.

TypeScript-wasm tools: AssemblyScript, TurboScript, Speedy.js

Using TypeScript has been coming more common, and Babel 7 will ship with TypeScript presets. For compiling TypeScript to WebAssembly, a new generation of tooling is required. TypeScript to JavaScript tooling is now pretty stable, but the TypeScript to WebAssembly space is still evolving at a rapid pace.

There are multiple options for compiling TypeScript to wasm, but there is no de-facto choice yet. Multiple tools available have reached a maturity where they are usable for real world development in limited cases. Application execution is guaranteed by the wasm spec — A compliant wasm binary will work identically regardless of the language it was written and the toolchain used for compiling.

The most common TypeScript to wasm compilers at the time of writing in February 2018 are:

Like WebAssembly itself, the TypeScript-wasm compiler scene is very volatile. The situation can be compared to the 2013-2015 when first task runners like Grunt and Gulp were prominent, but the industry then moved to Browserify for module bundler and eventually standardized on Webpack. It continues to evolve and there's competition from Rollup and Parcel, but the pace is more relaxed.

As of now AssemblyScript seems like the most promising of the trio of prominent compilers. It has a standard installation procedure via NPM, does not reinvent the wheel. Binaryen, a compiler and toolchain infrastructure library, is used do the heavy lifting. Binaryen originates from the core WebAssembly and thus is a high profile project with over 56 contributors. Seems legit to me.

In addition to pure technical ability, AssemblyScript is also investing in softer side of developer tooling; Example code, documentation and an online playground (WebAssembly Studio) are available. Today AssemblyScript only has two contributors, which is an obvious disadvantage. On the other hand, the project can be seen as glue code between TypeScript and Binaryen, so a small team can be credible.

Conclusion

The reality is that the vast majority of web developers, including myself, will likely never write a single WebAssembly application from scratch. Having the possibility to a use familiar language syntax and toolchain is a something that would lower the treshold to make changes to WebAssembly components.

It's important to understand the field is still very much in flux, but with three credible options available, I expect that in some years the developer community will standardize on one or two. I view today as the situation we had when JavaScript syntax went ES6+, but this time we've got a clue on what's coming.

Or who knows? Maybe Facebook will launch competing Zuckembly that will eat web standards' lunch, like with React. But until that day is upon us, the most important question on my mind is…

When will we get a Macromedia Flash plugin in WebAssembly, so we can all migrate to ActionScript?

-- Jani Tarvainen, 20/02/2018