If you are a web developer, or a software developer in general, you must have heard of something called WebAssembly
in last few years. If you did, but do not actually know what it is, and why you keep hearing about them - this post is for you. If you are already compiling your code into wasm
and loading them into your JavaScript
code, then you can happily skip.
If you’re in the first group, jump right in. Here, we’ll try to understand what is WebAssembly
, what is the context of it, the hype vs. the fact, and a bit of the future. You might have already come across bunch of articles, blog posts, tweets, videos & even conference talks about it, but still probably have no clue what it is? Is it a new tool, a design pattern or a shiny new JavaScript framework?
What is WebAssembly
WebAssembly is a new, low level binary code, for the web!
Wait, a what?
That’s right! That’s what WebAssembly
is. Let us take this definition apart, and understand piece-by-piece
- It’s a
new language
. It became the offical “fourth language for web” on 5th December 2019, i.e. after HTML, CSS & JavaScript - It’s
binary
, so it is not really human readable (it’s an “assembly” language for the web) - It’s
low level
, i.e. it’s much closer to actual machine code (thanJavaScript
and other higher level languages) - And it’s
for the web
, that means (modern) web browsers can read and execute them
So, how do I code in WebAssembly
?
Actual WebAssembly is a binary language. Though there is a text representation, you as a developer won’t generally “write” code in WebAssembly
! It’s actually an IR
or Intermediate Representation
code, comparable to ByteCode
in Java
or MSIL/CIL
in .NET
. It’s meant to be a compilation target for higher level languages.
Basically it’s a set of low level binary instructions that works across common standard hardware. Unlike higher level languages like C#
, Go
or Java
, it is more closer to machine language, and can be converted into actual machine code
very fast & efficiently. So rather than writing code in it, you still write code in a language that you already know, like C/C++
or Rust
, and a special compiler compiles your code into WebAssembly
, and that runs inside a special Virtual Machine
. This VM
can turn the IR
into actual, platform specific Machine Code
and execute them. This VM
can run on any type of platform (hardware + OS).
In a nutshell, that’s like the main idea behind WebAssembly, to be able to run pre-compiled code, written in any language, on the web!
Okay, but why?
Why WebAssembly
?
I cannot read or write code in WebAssembly! Then what is the purpose of it? Why have it as the fouth language for the web? We already have our good ol’ JavaScript
!
Yes, JavaScript
works, and it works pretty well. And there are really cool JS Frameworks
like Angular
, React
, Vue
etc. that make complex web development much easier. In fact JS
is so cool, that now lot of people even write back-end or server-side code in JS
, thanks to Node
!
BUT, there are issues with JavaScript
, mainly with performance
! It works fine for a standard web applications where small pieces of processing is done on the web, based on user interaction. Generally, the heavy processing is done on servers, and web interacts with them through http
services. But it does not work well when lot of real-time processing is required, think of - image & video processing, 3D gaming, AR/VR etc.
NOTE: JavaScript is an interpreted language i.e. at the run-time, each line of code is turned into machine code as it is encountered. This happens everytime, even the same line of code is executed multiple times (e.g. loops). This is inefficient. And there is no way to look at the whole code at once & ompimize. Also, the garbage collector cycles take it’s time to run and free up memory, stalling the applications. Well, this is how JavaScript used to run traditionally. But the modern JavaScript engines use JIT compiler
which partially compiles the code & has some performance improvements. But still it’s not the best we could get, partly because of the dynamic
nature of JavaScript. Learn more about them in this series of posts by Lin Clark.
Web has been an important medium of user interaction for software programs, and with modern SaaS & cloud applications, users are now enabled to do more & more stuffs on web. Users & developers, both want to be able to do more stuffs on web, and faster. And with frameworks like Electron
, web apps can run like native apps on desktop, cross-platform. Now, apart from JavaScript
being not-so-fast, always going over the network for any heavy processing & bringing back results, makes fast processing on web applications almost impossible.
WebAssembly
aims to solve this problem. WebAssembly is a new type of assembly language (Intermediate Code) that
- Any language compiler can target
- Can be executed on web, stand-alone
With that, developers can write their code on high-performance languages like C/C++
or Rust
and compile them into WebAssembly
. This IR
code matches very closely with machine languages across hardwares. Now the browser (with WebAssembly VM
s) can directly translate that into machine code & execute. This can make the code run real fast in near native (directly running compiled machine code) speed.
Important: For this to happen, 2 things are required. [1] Different languages need to compile into WebAssembly [2] Browsers need to be ready to run WebAssembly. For #1, different languages need to come up with new compilers that target WebAssembly rather than their standard IR. This is already available for C/C++
, Rust
and even C#
. And very soon we’ll have compilers for many other langues, some of them might be ready by the time you read this. And #2 is not an issue, as all the modern brosers already support WebAssembly viz. Firefox
, Chrome
, Edge
& Safari
. In fact, WebAssembly is a joint effort by W3C
, Mozilla
, Google
, Microsoft
& Apple
(and of course community members). So, all the major browsers should always be up to date with latest WebAssembly standards.
Points to remember
Now that we know what is WebAssembly and what problem it aims to solve, let’s look at a bunch of important points to note.
WebAssembly
is still a new & evolving technology. Things are changing very fast, and by the time you read, many things might have changed- It’s a low level binary code, meant to be target of compilation for higher level (ideally fast) languages. Any language that wants to generate
WebAssembly
, needs to come up with a compiler that compiles from that language toWebAssembly
IR - As a language, it’s strongly typed (unlike
JavaScript
) - It runs inside a
VM
(likeJava
runs indsideJVM
orC#
runs inside.NET CLR
). TheWebAssembly Virtual Machine
works like a Stack Machine i.e. all opeations work on the stack. For each operation, itpush
orpop
something on the internal memory stack (e.g. a functions pops operands from the stack, and at the end, the return value is pushed on top of stack) WebAssembly
is frequently abbreviated asWA
orwasm
. Actual WebAssembly files also have*.wasm
extension- Generally the binary size is pretty small (compared to
JavaScript
, even when compressed) & executes fast because of it’s near native model - On browser,
WebAssembly
runs with same priviledges asJavaScript
code, so it has the same security levels of current browser code (e.g. it cannot start manipulating files on client system, without explicit user action) - It’s portable & platform agnostic, i.e. indepndent of underlying
hardware
orOS
- There is a text representation of
wasm
, that is human readable and followss-expressions
format. Though it’s totally possible to write code inWAT
, the main idea behind this is to enabledebug
WebAssembly code at run-time (it’s not ready though) WebAssembly
enables web browsers to run code written in other languages thanJavaScript
.C/C++
andRust
were supported from the beginning..NET
already supports it through Blazor, and support for many other languages should be available soon- Some popular compilers for
WebAssembly
are LLVM & Emscripten. Currently Emscripten is the most popular compiler - To get the taste of first-hand
wasm
development, follow this Hello World tutorial
Why Wasm
is great
- Can have much higher performance than JavaScript
- Smaller download size, mainly for the binary format
- As code is already in IR (Intermediate Representation) code, it is much closer to machine code. So the whole code can be translated to stable machine code quickly rather than the optimize & re-optimize cycles of JS JIT compiler (also because the types are static)
- No Garbage Collection by design, so
GC
cycles are saved
- Code sharing
- It provides a simple and performant way of sharing
pre-compiled
(wasm
as IR is close to machine code) code across platforms, written indifferent languages
- Same
wasm
code can run in front-end as well as in the back-end, like standard server side code. So basically, code sharing between front-end & back-end. Note that it’s already possible withJavaScript
&Nodejs
, but that doesn’t provide speed of lower level languages likeC/C++
- It provides a simple and performant way of sharing
- Different
wasm
modules, written in different languages, can interoperate easily, making it very easy to collaborate between developers from different backgrounds and interoperate otherwise incompatible modules (this will become possible with implementation of interface types) - Works seamlessly with
JavaSCript
i.e.wasm
&JavaScript
can exchange data and call each other. In fact, currentlywasm
cannot be run withoutJS
becuase [1] It needsJS
to load thewasm
module [2]DOM
manipulation happens throughJS
only - With
wasm
we can truly relize serverless web applications, that can actually run without any backing servers (it can do heavy computations, connect to database and what not!) - Can also run outside browser, in a safe & fast manner.
Wasm
provides a light-weight sandboxing by default. More about this later
What’s not-so-great (yet)
- Not complete, or “ready” yet. Many features are still under development or in proposal stage
- Compilation and loading process is bit complex, and apparently no official integration into popular build tools like webpack or Angular CLI (this may change soon though)
- By design, code needs to be compiled before distribution. So, fix JS directly on CDN kind of approach does not work
Internet Explorer
and older versions of other browsers does not support- Some conventions of
wasm
makes it more complex for developers to write code. So, high level language compilers need to provide some extra layer for developers to code easily. For exampleWasm
supports only numbers as method parameters. To use any other types, one needs to work with memory locations / pointers directly (will be easier with the interface types implementation)- No automatic
GC
. Memory has to be managed manually
- Because of current not-so-optimized wasm invocation from
JS
, it doesn’t perform well if there are lot of small functions to be invoked (lot of jumping betweenJS
andwasm
) WebAssembly
, in the current form, cannot directly manipulate DOM. No direct access to the Web APIs. For that, it needs to go throughJavaScript
. Even for loadingwasm
modules, it has to depend onJS
- Not really debuggable for high-level language source code (should change in future with source-maps)
- No fully featured multi-threading support
NOTE: As WebAssembly is just in the early stage of development, specs proposals & implementations change fast. Many of the limitations mentioned above might not apply in future. And that may happen pretty soon.
WASI
- run WebAssembly
everywhere
If we think about about the core working principles of WebAssembly
, it’s not difficult to visualize wasm
executing outside web browsers as well! Provided the WebAssembly Virtual Machine
is available, wasm
code can run in any system on any platform, browser or not!
Developers are already running wasm
outside browsers for the amazing benefits it provides - fast, scalable, secure way to run the same code across all machines.
Now the wasm committee is also pushing the idea, and working to provide a standard set of interfaces so that - wasm
applications written in different languages can run acorss platforms, talk to each-other seamlessly, can access necessary system APIs & execute securely inside a sandbox (with controlled access, memory, network, filesystem etc). Thasts WebAssembly System Interface
or WASI. Read this for more details.
Now think of the implications. WASI
, if works as expected, will open up crazy new ways of writing applications - on any language, that runs everywhere, and talk to each other fluently without any wrappers or network calls!
When WASI
was proposed, Docker
co-founder & CTO Solomon Hykes tweeted, if WASI
was already available, Docker
wouldn’t have been necessary!
Take a moment. Or two. And think about that! 🤯
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! https://t.co/wnXQg4kwa4
— Solomon Hykes (@solomonstre) March 27, 2019
A few finals notes
- When can I start using
wasm
? Right now! Though it’ll change a lot in future, it’s already available to use and it really works! - Will it replace
JavaScript
? No. At least not any time soon. Currentlywasm
depends onJS
for loading & any kind ofDOM
manipulation. Though it’ll change in future,JS
is already huge and has it’s own high place in web development. Practically, it’s the only language tailored fit for web development, other languages - not really. All the amazing JS frameworks also make it almost irreplacable. So, probably no existingJS
based web applications will be re-written inwasm
, but a time might come when new web applications might be written completely inwasm
(in a language likeC++
,Go
,Kotlin
or something that doesn’t even exist today)! - Why not re-write all the web apps in WebAssembly? For typical web apps, where it’s the app that’s waiting for user most of the time, and needs to talk to a remote database to get data,
wasm
will not provide much performance gain. So all the development, testing, integration effort will not be worth it. - What about
Docker
? Willwasm
replace it? “No, but imagine a future where Docker runs linux containers, windows containers and wasm containers side by side. Over time wasm might become the most popular container type. Docker will love them all equally, and run it all :)” - Solomon Hykes - Ok, so what about
JS developers
? Is it like all the JS developers will now have to learn a completely new language (maybe more than one?) just to keep up with web development? Well, learning a new language might be really helpful, mainly to benefit from the performance of lower level languages. But it may not be necessary. For instance, there is already a popular language AssemblyScript that can compileTypeScript
(a subset actually) intoWebAssembly
. - So, now we’ll see back-end developers start doing front-end development? Not very soon probably. But it will happen definitely. With the advent of
Nodejs
, we saw front-end developers become “full-stack” developers. Once wasm gets more stable (and DOM access), we may see the reverse trend of typical back-end developers becoming “full-stack” developers! But front-end development requires some specific expertise (DOM, HTML, CSS etc.) & a different programming paradigm, which only comes with time.
Disclaimer: I’m by no means a WebAssembly expert. I’m just a developer interested in the development & future applications of WebAssembly. My whole source of knowledge was my research on wasm, to see if it could solve a specific problem that I was not able to solve with current web technologies. Though I figured out that wasm, in it’s current state, cannot solve the problem, but all the amazing articles and talks (few mentioned in references below) got me really excited about WebAssembly and all the new possibilities it opens up! 😄
References
- The WebAssembly home page
- GitHub repos
- Mozilla WebAssembly docs
- A cartoon intro to WebAssembly
- Wasm Hello World guide
- Tools
- Wasm Text Format WAT
- WASI
- AssemblyScript
- Videos
- Also look at this WebAssembly logo contest from 2015, just for fun