Adam Innes · Blog

WebAssembly Was Just Announced: What It Is and What It Isn't

· 8 min · webassembly, javascript, asm.js, web standards

Last Wednesday, June 17, a new name showed up in several browser vendors’ corners of the internet at once. Luke Wagner wrote on his Mozilla blog that Mozilla had started working with Chromium, Edge and WebKit engineers on a new standard called WebAssembly. Mike Holman posted on his Microsoft MSDN blog the same day that Microsoft had been talking with developers from Firefox, Chromium and WebKit and had come to general agreement on a shared set of goals. And on the WebKit side, Filip Pizlo opened a WebKit bug that morning proposing that JavaScriptCore support WebAssembly natively, noting that the standard has broad support.

The two questions I’d expect most web developers to ask are whether they can use it yet and whether it’s coming for JavaScript. Going by what the people designing it actually wrote, the answers are not yet, and no.

A design effort, not a browser feature

No browser ships WebAssembly support, and the binary format hasn’t been specified. Wagner’s post is upfront that it’s very early: there’s no draft spec, no formal standards body chosen yet, just a W3C Community Group, some initial prototyping, and early cross-browser consensus on a set of high-level design documents. Holman’s post calls the design incomplete and likely to change. The README of the design repository puts it in bold that everything is still tentative, and says the actual specification will be drafted in a different repository.

The WebAssembly Community Group describes its mission as early-stage cross-browser collaboration on a new, portable, size- and load-time-efficient format suitable for compilation to the web. The group was proposed by Luke Wagner and launched back on April 29, so the group existed for about seven weeks before the public announcement. W3C hosts Community Groups, but they’re run by the community, and the page notes they don’t necessarily represent the views of the W3C membership or staff. This isn’t a W3C Recommendation, or anywhere close to one.

What the design docs say it is

The high-level goals document is the best single summary, and it’s short. The core idea is a portable binary format that’s small to download and fast to load, meant as a compilation target that can run at native speed by using hardware capabilities common across a wide range of platforms, mobile included.

The plan is incremental. First comes a Minimum Viable Product with roughly the same functionality as asm.js, aimed primarily at C and C++. Alongside it, a polyfill library that translates WebAssembly into JavaScript on the client so the MVP can run in browsers that exist today. After that, a follow-up with more essential features, and then further features driven by feedback, including better support for languages beyond C and C++. On the tooling side, the goals call for a new LLVM backend for WebAssembly with a matching clang port.

The goals also say WebAssembly should fit the web as it already works: versionless and feature tested like the rest of the platform, running in the same semantic universe as JavaScript, with synchronous calls in both directions, and with a human-editable text format that converts to and from the binary so View Source still means something. Running outside the browser is listed as a goal as well, though the browser is clearly the main event.

Why not just keep using asm.js

If you haven’t run into it, asm.js is the approach that already works today for running C and C++ on the web. Its working draft spec, last updated in August 2014 with editors from Mozilla, defines it as a strict subset of JavaScript that works as a low-level, efficient compiler target, effectively a sandboxed virtual machine for memory-unsafe languages. Because it’s plain JavaScript, it runs in any engine, and engines that recognize it can compile it ahead of time. The spec says Mozilla’s SpiderMonkey engine has an optimizing implementation, and Holman’s post mentions Microsoft adding asm.js optimizations to Edge on Windows 10. Emscripten is one of the compilers that produce it from C or C++.

So why a new format? The design FAQ gives two reasons. The first is parsing. A big compiled app is a huge amount of JavaScript text, and the FAQ says that on mobile, large compiled code can take 20 to 40 seconds just to parse. A binary format can be decoded natively much faster, and the FAQ cites experiments showing more than 20 times faster. The second reason is room to grow. asm.js has to stay ahead-of-time compilable while also running well in engines that have no special asm.js support, and holding both of those at once makes it hard to add the features needed to reach native performance. A separate format drops those constraints.

Diagram comparing today’s C/C++ to asm.js pipeline with the planned WebAssembly binary, decoded by a polyfill or natively

The FAQ is also honest about cost. Every new standard brings maintenance, attack surface and code size. The argument is that the design allows, but doesn’t require, a browser to build WebAssembly inside its existing JavaScript engine, reusing the compiler backend, the ES6 module loading frontend and the security sandboxing it already has. By that logic it should cost about as much as a big new JavaScript feature rather than a fundamental change to the browser.

The polyfill is the clever part

The piece that makes this more than a wish list is the polyfill plan. Before any browser supports WebAssembly natively, you’d ship the binary along with a library that converts it to JavaScript in the browser. You get a smaller download thanks to the binary encoding, a small startup hit from the decoding, and the same throughput asm.js already gets. It also lets the group get developer feedback on the early binary encoding before locking it down. There’s a working prototype that unpacks a tentative binary format into JavaScript and can also convert existing asm.js into it.

The FAQ has early numbers from that prototype, and it’s careful to say the binary format isn’t specified in any detail yet. Using the AngryBots demo, the asm.js build is 19 MiB against 6.3 MiB for the prototype binary. After gzip, it’s 4.1 MiB against 3.0 MiB. The decoder itself is C++ compiled to asm.js with Emscripten, and the FAQ reports it turning that 6.3 MiB binary back into asm.js in 240 milliseconds in Firefox 41, faster than a native JavaScript parser can parse the result. Add decoding while downloading and better than gzip compression, and the FAQ extrapolates to roughly a 45% smaller download than gzipped asm.js today without hurting load time, assuming a moderately fast network and more than one CPU core.

Bar chart of AngryBots demo sizes as asm.js and as the prototype binary, before and after gzip

Those are prototype numbers from the people building it, on two demos, so I’d read them as “promising” rather than as a benchmark. The polyfill doc also admits a practical polyfill may deliberately differ from the spec in corner cases, like out of bounds heap access following asm.js behavior, where being exactly correct would be too slow. For existing Emscripten users, the FAQ says moving to WebAssembly should come down to flipping a flag, with Emscripten initially converting its asm.js output.

What it isn’t

It isn’t a JavaScript replacement. The FAQ answers that question directly and emphatically: WebAssembly is meant to complement JavaScript, and JavaScript is expected to remain the single privileged dynamic language of the web. The setups it expects are mixes, like a compiled C++ app that uses JavaScript as glue, an HTML, CSS and JavaScript interface around a canvas driven by WebAssembly, or a mostly JavaScript app that pulls in a few fast modules for things like image processing or compression. The browser embedding doc sketches modules loading the same way ES6 modules do and showing up to JavaScript as ES6 module objects, so a JavaScript developer could use a compiled C++ library without writing any C++.

Diagram of JavaScript and a planned WebAssembly module side by side on a page, sharing Web APIs and security policies

It isn’t a way around the web platform either. WebAssembly doesn’t define its own APIs or system calls, just a way to import things the host provides, and on the web that means the same Web APIs JavaScript already uses.

It isn’t a new text language browsers will parse. The text format exists for View Source, developer tools, and people writing or studying modules by hand, and the text format doc says browsers won’t parse it on regular web content to run WebAssembly.

And again, it isn’t shipping. None of the announcement posts or design docs give a release date, and the MVP they describe doesn’t exist yet.

The security model, as drafted

The MVP document has a one-sentence security section, and it’s the right place to start: the MVP will be no looser, security-wise, than if the module were JavaScript or asm.js. The high-level goals back that up by requiring WebAssembly to enforce the same-origin and permissions policies and to reach browser features only through the same Web APIs JavaScript can use. In other words, no new powers for code that happens to be compiled.

The browser embedding doc says the security model should rely on CORS and Subresource Integrity, which matters if modules get served from CDNs. In the MVP, each module gets its own heap that other modules can’t access directly, and the semantics doc says a function pointer’s integer value is an abstract index rather than the real machine code address. The ideal behavior for out of bounds memory access is a trap, which stops the module and would surface as a JavaScript exception in a browser, although the doc lists a few variations still under discussion.

The part I’d pay the most attention to is in the C and C++ doc. Undefined behavior in your C code is still a bug when compiled to WebAssembly. It can’t break out of the sandbox or corrupt the call stack, but it can corrupt the application’s own heap, call APIs with arbitrary parameters, hang, or trap. So the sandbox keeps a bug contained inside the module, but it doesn’t protect your app’s own data or logic from that bug. My take is that a compiled module deserves the same trust decision as any third-party script, because a memory bug inside it runs with your page’s origin and your page’s API access.

What to do with this right now

If you already compile C or C++ to asm.js with Emscripten, you’re on the path the FAQ describes, and there’s nothing to change yet. If you’re curious, the design README suggests starting with the high-level goals and then the FAQ. The Community Group is open to anyone with a W3C account, W3C membership isn’t required, and the design discussion happens in the open on GitHub.

The takeaway is that WebAssembly, as of this week, is a shared plan: a compact binary format for compiled code, polyfilled to asm.js first, living next to JavaScript under the web’s existing security rules. The interesting news isn’t a feature. It’s that Mozilla, Microsoft, WebKit and Chromium engineers are all working on the same design documents, and I’d call that a better start than most web standards get.

← all posts