What Is a WebAssembly Component? The Ultimate Guide
What Is a WebAssembly Component?
A WebAssembly component plays a critical role in how runtimes that run inside WebAssembly modules are deployed. But its standardization is still being worked out.
Once finalized, a component model that will enable WebAssembly to not just see its expanding use beyond web browsers and servers — but will be able to allow users to deploy different applications running inside numerous light-weight modules at very high speeds across thousands of endpoints simultaneously through a component interface called the WebAssembly System Interface (WASI) without changing one iota of code.
That is the theory at least, but again, the community is working on getting there. At the same time, there is a lot of confusion about what a component is and how it factors into WebAssembly’s adoption.
How Do WebAssembly and Components Work Together?
Before digging in deeper about what a component is, and its functionality, we first need to describe what WebAssembly is, and how its evolution has led to the need for a component model and especially its relationship to the WASI, which is the standard Interface or API linking the web assembly modules to the components.
WebAssembly is designed to deploy applications written in the language of the developer’s choice, enabling simultaneous deployment in various and disparate environments. Disparate” here means that WebAssembly runs on a CPU and only requires a device, server, etc., capable of running a CPU instruction set.
This means that a single deployment of an application in a WebAssembly module should theoretically be able to run on and be updated across a multitude of different devices, including servers, edge devices, multiclouds, serverless environments, and more.
Different applications written in diverse programming languages should be able to coexist within a single module, although this capability is still largely under development.
In essence, a microservices-packed module should be able to deploy multiple services across various environments and provide application updates without reconfiguring the endpoints.
In theory, it’s simply a matter of configuring the application within the module, so that each environment in which the module is deployed doesn’t require separate reconfiguration once the work is completed within the module. However, this also depends on the finalization of a component standard.
How Did We Get from Web Modules to Servers with Components?
Now, as we observe with Kubernetes and Docker, the aspiration to deploy applications simultaneously everywhere hinges on standardizing the component model.
This model is often likened to Lego blocks. These components serve as the interface through WASI to which the web assembly module provides runtimes. These components are stacked together, linking them to harness the versatility and power of various WebAssembly runtimes into a unified package or unit comprising components.
The beauty of this approach is the security it affords, much like how Kubernetes ensures components do not share data in memory, namespaces, or namespace allocation. They maintain a closed or sandboxed interface through the WebAssembly bot modules.
However, achieving standardization is the challenge; enabling components to run on any system is the goal. This would allow the web assembly module to interact seamlessly with the component, deploying and running on a CPU instruction set. While it is configured to do so for any module adhering to the standard, this standard remains a work in progress, representing the final mile of WebAssembly’s journey.
Presently, the development of components plays a crucial role in the open source community’s efforts to advance WebAssembly. The standard component interface is being established in an innovative manner, heralding a world of possibilities.
Numerous open source projects and research initiatives are contributing to this finalization process. For developers, especially those akin to Kubernetes, the inner workings and mechanisms of component development may not hold much interest. They primarily seek the end result: the ability to run and deploy applications as they wish, as WebAssembly increasingly integrates with Kubernetes.
This may remind you of the emergence of DOS in the ’80s and ’90s when volumes of books delved into file interactions, configurations, and DOS commands. However, understanding these intricacies was not crucial for most programmers and software engineers, especially considering the dominance of Unix and Linux in the software development landscape.
What Is a Component Composed of?
During a keynote at WasmCon held in September, Luke Wagner, distinguished engineer, for Fastly, which relies heavily on WebAssembly for certain services on its edge delivery platform, described what a Wasm component is in one phrase: an emerging, standard, portable, lightweight, finely sandboxed, cross-language and compositional module.
A component is a module that contains imports, internal definitions, and exports, he explained. Imports include elements such as imported functions (e.g., a log function) and generally capture the I/O the component provides and its implementation dependencies, rather than relying on a fixed set of system call or a fixed runtime global namespace.
Internal definitions represent the core code that runs, primarily consisting of embedded Wasm modules, “and this is where 99% of the bytes reside. Internal definitions can also call the imports,” Wagner said.
“Components can further nest other components, making them inherently recursive,” Wagner said. “Lastly, exports make internal definitions and imports public to the component’s clients by assigning names and types.”
In the container world, the Open Container Interface (OCI) defines the standard for distributable containers. Docker build creates a container from sources, Docker run and Kubernetes run and deploy it, and for sharing and composition, Docker push and Docker compose come into play, Wagner said.
“So the natural question arises: can we use Wasm for this purpose?” Wagner asked. “It’s undoubtedly a standard distributable format, but the challenge is that Wasm primarily supports shared memory linking. When we want to link two Wasm modules together, they typically need to share memory to pass compound values through that shared memory, which is similar to operating system DLLs or shared objects.”
However, when two or more Webassembly modules are composed, they should retain their own separate memories that aren’t shared, Wagner said. There is a need for a way to pass complex values between them and transfer ownership of resources, which can’t be copied between them, resembling an operating system executable, he said.
It Is Possible to Wrap Wasm Modules with a Portable Operating System Interface (POSIX) to create a Wasm Executable?
Distributing a single POSIX executable is often not sufficient because we typically need to distribute a collection of executables that must work together, along with configuration files, static assets and a directory structure, Wagner said. A solution might be to bundle Wasm modules into a container with Wasm as the instruction set at the core, Wagner said.
“While this approach can be useful, it doesn’t unlock the exciting new use cases we’re envisioning,” Wagner said. “To achieve that, we need something new, a wrapper for Wasm that allows us to use existing compilers. This new concept is what we’re proposing and calling a “component.”
What Happens Next?
It is necessary to keep in mind that business models are being built on WebAssembly thanks to its unique capabilities and this largely depends on the finalizing the component model.
Already, developers who are choosing Wasm “to run code where they couldn’t otherwise,” Wagner said.
“This causes us to build a set of reusable tools that enable a first wave of languages and APIs. But because these tools aren’t coupled to just one platform, they’re kind of generally using the component model and we can now attract a new wave of platform builders who are now tapping into this meta ecosystem and getting a bunch of stuff they didn’t have to build themselves,” Wagner said.
“This can attract a big newer wave of developers who are now choosing Wasm for its ease of reuse and productivity in all these reusable components. And then this can cause us and lead us to build a whole new wave of tooling that allows us to compose applications out of components and a whole new kind of developer programming models.”
It’s essential to keep in mind that business models are emerging around WebAssembly due to its unique capabilities, and much of this depends on finalizing the component model.
Currently, developers are opting for WebAssembly to “run code where they couldn’t otherwise,” as highlighted by Wagner. This has prompted the development of a set of reusable tools designed to enable the initial wave of languages and APIs.
Since these tools aren’t tied to a single platform, they’re widely employing the component model. Consequently, a new generation of platform builders is entering the scene, capitalizing on this meta-ecosystem and gaining access to numerous resources they don’t need to develop from scratch.
As a result, a newer wave of developers is gravitating toward WebAssembly, attracted by its ease of reuse and the productivity it offers through these reusable components. This, in turn, leads to the development of a new set of tools for composing applications from components and creating a novel developer programming model.
What’s the Current Status of These Developments?
There is a formal specification in the works, complete with operational semantics, a reference interpreter and a reference test suite, Wagner said. Significant portions have already been implemented in Wasm time with BindGen and Wasm tools. An upcoming milestone, aimed for early next year, involves synchronizing components with full parametric linking, value, resource, and handle types.
Following that, the major milestone is adding future and streams to the component model, introducing asynchronous support. “This will be a challenging step but will streamline much of the otherwise duplicated work. Finally, there are some remaining elements to wrap up a component model MVP, such as optional imports and exports,” Wagner said.