Building the component model for Wasm

The WebAssembly component model lays the groundwork for a language-agnostic component system, one that allows any Wasm application to use components written in any programming language.

shutterstock 1638222700 lego blocks components modules assembly
goir / Shutterstock

There are several new standardization efforts happening within the WebAssembly (aka Wasm) space, including what we believe to be a new way to write software applications. As a way both to describe this new model and to indicate where we are heading with WebAssembly standards in general, I would like to dive into some of the history of Wasm.

The design for WebAssembly began in 2015, years before officially becoming the fourth language of the web in 2019. While many technologists are familiar with Wasm as a browser technology, Wasm itself does not depend on JavaScript or web APIs.

Wasm’s precursor, asm.js, rose to prominence in 2013. A subset of JavaScript that is highly optimizable for browsers, asm.js also can act as a compilation target for languages like C and C++. One of my all time favorite talks, The Birth and Death of JavaScript, by Gary Bernhardt, covers a fictional future inspired by asm.js. If you watch this talk, which Gary presented at PyCon 2014, you can’t help but note the similarities between the future we eventually pave with Wasm and Gary’s predictions.

I often call asm.js the greatest hack of all time (in the most loving way). Who would have thought a high-level scripting language could be A) a compilation target and B) so incredibly fast? In 2012, I ported several C++ libraries to asm.js and felt that I had unlocked the secret code to a portable universe.

The technology proved several things. First, there is a need and desire to bring other languages to the web, but developers didn’t want to stop there. The types of applications being ported were computationally and graphically demanding, from data visualization tools (like the components I worked on at SAS), to games built with Unity and Unreal Engine (UE3 was ported in four days).

That’s why when the W3C WebAssembly community group and the corresponding WebAssembly design repository were created in 2015, browser vendors like Mozilla, Google, Microsoft, and Apple were among the first contributors to the effort and the first to see a tangible opportunity. The design called for a language with a binary format that could be used as a portable compilation target, that was optimized for size to enable fast downloads, and that had support for streaming compilation, which allows the downloaded module to have near instant instantiation. Most importantly, these modules must facilitate sandboxed execution environments, as any arbitrary code run in browsers must.

Why Wasm beyond the browser?

Much of what was learned in browser-side deployments gave clues to the many ways in which Wasm could fulfill its potential beyond the browser. The “cloud” makes up a heterogeneous set of compute architectures, operating systems, and system constraints in a world-wide network of machinery.

Consider some of Wasm’s key properties as a portable compilation target that is fast, sandboxed, and easily distributed thanks to the compact binary format. These properties of Wasm make it the perfect distributable unit of compute for the cloud. Additionally, companies want to build applications for different environments, but don’t want to have to refactor every time. Wasm removes these barriers.

When I first learned of asm.js, I was on the hunt for a solution for how to take our existing Flash application to HTML5. This ActionScript/Flex app was a rewritten version of its Java counterpart, which was a port of earlier versions of the same business logic written in C. This story might seem wild to you if you haven’t worked in large enterprises, but you can find this type of porting between each epoch of computing in every organization that is lucky enough to survive the test of time.

Wasm allows total portability to any Wasm-compliant runtime including browsers, runtimes that are purpose-built for FaaS, or runtimes designed to run on tiny architectures for IoT. In the web, Wasm modules are able to use JavaScript “glue” code to access web APIs like WebGL, networking, and devices to do things beyond pure computation. At the end of the day, a Wasm program really only operates on numeric values. (Or said differently, a Wasm module is a bunch of i32s in a trench coat.) In order to do interesting things, a Wasm module needs to be able to call functions from the host runtime.

WASI: The frontier of server-side Wasm

Around the same time that WebAssembly 1.0 became a recommended web standard, a new subgroup within the W3C WebAssembly working group was created for exploring a systems level interface for WebAssembly known as WASI (WebAssembly Systems Interface). The group has been working on creating a set of standardized interfaces ever since.

WASI exists to make WebAssembly work well anywhere, not just within the browser, but the key defining feature of WASI is its capability-based security model. Capability-based security has been around since the 1960’s (Dennis and Van Horn, 1966), but Dan Gohman architected a new take on this by building on ideas from Cloud ABI.

Understandably, this technology soon attracted the attention of companies interested in running Wasm outside the web. Companies like Fastly, Intel, Red Hat, and Mozilla saw a chance to put Wasm to work in the cloud, on devices, and at the edge. Those companies were the founding members of the Bytecode Alliance (BA), a non-profit organization for building secure software foundations for Wasm using standards like WASI. Many other organizations soon joined the BA, including major players across the software industry. The BA now stands at over 30 members, and it’s growing!

Over the last couple of years, we’ve made massive progress towards building the necessary tooling to run Wasm in cloud native applications. The community learned a great deal from these early experiences, which led us to create a new standard we call the component model. The component model is at a lower level than WASI. It works well with WASI but it’s not dependent upon WASI.

The component model is the result of our envisioning a broader software ecosystem for Wasm—not just based around a portable unit of compute, but something bigger and entirely new, with composable, interoperable, and platform virtualizable WebAssembly modules. Let’s break that down.

  • Composability: Allow for modular code reuse in a language-independent way.
  • Platform virtualization: The ability to layer in the platform-specific pieces that a component needs to run in a given environment. An earlier proposal for the feature for platform virtualization and composability was called module-linking.
  • Interoperability: With composable and virtualizable components, we need a way to exchange information between components. We started with a proposal called interface-types, but this too is now a key feature of the component model proposal.

This is the story of how the component model started to take shape. Each one of the previous proposals have now been refined into this overarching standard. We expect to see the next major stable iteration of WASI standards and the component model later this year.

What is the WebAssembly component model?

In the WebAssembly component model, developers can pick and choose pieces of their application, implemented in different languages, as different value propositions. As developers begin creating Wasm component libraries, other developers can treat them as the world’s largest crate of software “Lego.”

In a full-circle moment, we believe new innovation will come when the component model starts to influence the way we write web applications. This makes sense when considering the web is one of those cool but constrained environments, with very impatient users—a breeding ground for fresh experimentation.

For example, I expect components to make designing a language-neutral plugin system for a web application even easier. If there were a piece needed for a language runtime like Python, multiple components that leverage that language runtime could use it. Compare this to today’s world, where we only have Wasm modules (not components) and these are typically built with all of Wasm’s compile-time dependencies baked into a single binary. If a large application were to support third-party plugins, then likely each Wasm plugin will have duplicate dependencies leading to size and memory bloat and slower downloads.

With a future system of Wasm components for the web, where a single application may have their choice of components written in any language, an application will only need to download exactly what it needs and interact with components like any other ES module with an import. In this world, the best component will rise to the top. The best could mean the fastest or the cleanest API, but most importantly its defining characteristic will not be the source language. May the best component win!

Building a stable technical foundation for WASI and components

A huge part of making WASI standards and the component model real is the role the BA plays in creating a usable technical framework: the SDKs, tooling, and core components. All must be built in a consistent and secure way, and accessible by all as examples of best practice.

Equally, the role of the Technical Steering Committee (TSC) of the BA will be critical in providing technical governance and support for every BA project. We work alongside the folks designing the best possible set of standards in the W3C WebAssembly and WASI working groups, which means we collaborate with them to make sure everything works in practice. The W3C WebAssembly and WASI groups are focused on the finalization of these standards, and the BA is focused on making them consumable within the community as quickly as possible to establish an active feedback loop.

Another important part of the BA’s charter is to enable language and environment interoperability. The BA provides tooling for generating language bindings for many different languages, but achieving language interoperability nirvana will also require registries and package managers in various language ecosystems to interop with Wasm components. That is why we are working on designing a registry protocol, called warg, as part of SIG-Registries. The goal is to enable any registry that implements this protocol to publish, consume, store, and share Wasm components.

Perhaps the most critical piece of any Wasm software stack is the Wasm runtime, and the BA hosts two. Wasmtime, written in Rust, is often the test bed for experimenting with new WASI and WebAssembly proposals. The WebAssembly Micro-Runtime (Wamr), written in C, supports many architectures including tiny ones like ESP32. Both of these runtimes act as great reference implementations of a Wasm runtime. The SDKs and tools for building a Wasm module are in line with Wasm standards, so any standards-compliant Wasm runtime (including those not hosted by the BA) can build on these software foundations.

Given all of the new and exciting standards evolving through WASI and the component model, and the implementations from the Bytecode Alliance, 2023 promises to be an exciting year for Wasm!

Bailey Hayes is director at Cosmonic and a director of the Bytecode Alliance Technical Steering Committee.

New Tech Forum provides a venue to explore and discuss emerging enterprise technology in unprecedented depth and breadth. The selection is subjective, based on our pick of the technologies we believe to be important and of greatest interest to InfoWorld readers. InfoWorld does not accept marketing collateral for publication and reserves the right to edit all contributed content. Send all inquiries to newtechforum@infoworld.com.

Copyright © 2023 IDG Communications, Inc.

How to choose a low-code development platform