803 karma · joined November 20, 2018
I am a maintainer for Wasmtime and work on many related projects: * Sr Principal Engineer at F5, working on WebAssembly (2024-) * former Co-chair of the WebAssembly CG's WASI Subgroup (2023-2025) * At-large Director on the Bytecode Alliance Board (2024-2025 term).
As someone who works on the Component Model, this perception is interesting to me, can you explain your thinking a bit more? From my perspective, getting data in and out of modules is indeed solved. Worlds are a type signature that describe what datatypes and methods are available in a particular embedding, with standards for command line and http proxies, but easy to define whatever your situation requires.
An additional benefit of using a fast JS runtime inside of WASM, even on a WASM engine that natively supports JS, is to use a Wasm Component as a security boundary around JS code. This could be used as an means of isolating supply-chain security issues, or allowing users to provide (untrusted) JS code that extends an existing system while having a clear and strong boundary on how untrusted JS code can affect the host JS code.
The jco project (https://github.com/BytecodeAlliance/jco) provides an implementation of the Component Model and WASI Preview 2 for JavaScript systems. Right now, node.js support is complete, but support for Web embeddings is in progress and coming soon.
> These interpreted languages can run in WASM, but only as language interpreter inside the WASM interpreter - so they work, but they are not efficient.
The Bytecode Alliance has made big improvements to SpiderMonkey performance on WASM/WASI systems, and has work in progress to take advantage of SpiderMonkey's "native" codegen targeting WASM: https://cfallin.org/blog/2023/10/11/spidermonkey-pbl/. We targeted JS first for this work because it is the most popular language with our customers and users, but we expect that this will show the path to adding similar improvements to Ruby, Python, and other languages commonly thought of as "interpreted".
At the end of 2023 we counted around 40 contributors who have been working on WASI specifications and implementations: https://github.com/WebAssembly/meetings/blob/main/wasi/2023/... . That is a great growth for our project from a few years ago when that issue was filed, but as you can see from what people are working on, its all much more foundational pieces than a graphics interface. Also, if you look at who is employing those contributors, its largely vendors who are interested in WASI in the context of serverless. That doesn't mean WASI is limited to only serverless, but that has been the focus from contributors so far.
By rolling out WASI on top of the WASM Component Model we have built a sound foundation for creating WASI proposals that support more problem domains, such as embedded systems (@mc_woods and his colleagues are helping with this), or graphics if someone is interested in putting in the work. Our guide to how to create proposals is found here: https://github.com/WebAssembly/WASI/blob/main/Contributing.m... .
Right now jco will automatically generate the JS glue code which implements a Component Model runtime on top of the JS engine's existing WebAssembly implementation. So, yes, Components are a composition of Wasm Modules and JS code is handling passing values from one module/instance to another. You still get the performance benefits of running computation in Wasm.
One day further down the standardization road, we would like to see Web engines ship a native implementation of the Component Model, which might be able to make certain optimizations that the JS implementation cannot. Until then you can consider jco a polyfill for a native implementation, and it still gives you the power to compose isolated programs written in many languages and run them in many different contexts, including the Web.
(Disclosure: I am co-chair of WASI, Wasmtime maintainer, implemented many parts of WASI/CM)
The component model tooling is getting very close to maturity and will solve many of these problems.
Wasi Preview 2, which we are aiming to launch by the end of the year, rebases Wasi on the Component Model proposal, which enables composition of Wasm programs, including those which are written in different languages, and which do not trust each other. Wasi is now specified in the Wit IDL, which has a strong type system for representing records, variants, lists, strings, and best of all, external resources, including sugar for constructors, methods, and destructors.
Instead of basing everything on the filesystem abstraction, the core Wasi primitives are the `input-stream`, `output-stream`, and `pollable` resource types, for readable and writable bytestreams, and a pseudo-future: you can `poll-oneoff` on a `list<pollable>` and it will block until one is ready, and return a `list<bool>` indicating the set which are ready. `wasi:filesystem/types.{descriptor}` is the resource for files, but if you need to read, write, or append to a file, you can do so by calling a method on `descriptor` that returns a `input-stream` or `output-stream`.
Preview 2 is also adding networking: wasi-sockets for platforms which support sockets, and wasi-http for those which don't, like the Web.
We are closing in on shipping Wasi Preview 2 but its not quite fully baked yet - changes related to resources are slated to land in the net few weeks. The spec definitions are on github: https://github.com/WebAssembly/wasi-io/blob/main/wit/streams... https://github.com/WebAssembly/wasi-filesystem/blob/main/wit... . Stay tuned for much more approachable documentation, tutorials, and so on, once we are confident it is a stable target ready for users.
You can also run these same components server-side with Wasmtime.
In general the Wasm Component ecosystem is still a few months away from being generally useful. There are a lot of people across the bytecode alliance working on the fundamentals right now, and we are making great progress, but its not ready to ship quite yet.
The remaining piece of the puzzle would be to create a wit-bindgen guest generator https://github.com/bytecodealliance/wit-bindgen#guests for this build of the python interpreter. You could then seamlessly call back and forth between the host and guest pythons, without even knowing that wasmtime is under the hood.
I swapped carrying a ham radio for a Garmin inReach a few years ago and it has been far more useful. I pay an annual service charge, but in return I can let my partner know I’m safe a few times a day, and I can use it to arrange for rides, neither of which I could do via ham. I have never had a problem getting reception, and it’s a much smaller, lighter device, and it recharges via USB so I never worry about spare batteries.
There are some ham specific activities for carrying a radio on the trail, like summits on the air, but if you are just trying to go hiking, get an inreach.
* the component model wat can represent interfaces, but it can’t represent the composition of interfaces, e.g. if we were writing a new interface which opened something file-like and wanted to reuse the oflags type from wasi-filesystem, there would be no way to express that indirectly because we insist wasm binaries are self contained (don’t require you to load other resources), so the oflags type definition would need to be copied in literally.
* when we add resource types back to wit syntax (you can rewind history in wit-bindgen 2 months to find examples, we got rid of them because they were a strawman and now something quite similar is getting speced) it’s nice to have wit syntax appear just like constructors and methods, even if we all know a method desugars to a functions that take a resource as it’s first parameter in the canonical abi. It’s nice to have a distinction in wit that can be used by code generators for creating idiomatic C++, Rust, JS etc methods. Even if we give methods a faithful wat/binary repr (like, e.g. flag types, which are a shorthand for a struct full of bools), the wat/binary form will necessarily have much worse syntax than the wit will, and we think having a syntax that doesn’t send you rubbing your temples reading the component model spec will help adoption.
Speaking as someone who has had to read and write a nontrivial amount of wat over the last 5 years, it’s lovely for small examples and it’s pretty challenging for large, “real world” programs.
WASI development has indeed been quite slow. Most of our efforts for the past 2 years have been developing and implementing the Component Model proposal. Right now we are working on porting WASI to the component model, which has been pushing all of the new wit tooling more than it has WASI itself.
I can’t really say that adding more people would have sped up the last few years. The vision of the component model is very ambitious - it’s the first credible open (as in, not owned by Oracle or MS) standard for a real cross language VM, and the security posture supports mutually distrustful components by default. If we had just iterated on the witx version of wasi without coming up with the component model first, I believe both the component model and wasi would be worse off for it.
A lot of the foundational spec work and tooling is now (hopefully!) pretty stable. We used to rewrite everything related to the component model (fka interface types or module linking) every 6-9 months because the spec changed really radically, now I genuinely believe you’ll be able to take todays wit-bindgen to production in 6-9 months of polishing. We are approaching the point where we can get those tools in the hands of way more contributors and the ecosystem can grow.
So yes, the contributors to it today are small, but they are growing (I’ve spent a big chunk of the last few weeks bringing on more contributors from other bca companies) and soon will be able to grow even more.
Native code might assume that code it calls won’t misbehave in these ways, but wasm guarantees it, and that allows wasm VMs which run untrusted code to have more efficient implementations.
Sandboxing also goes a long way towards containing the supply chain security issues that every language is susceptible to.
1. Spidermonkey.wasm is the basis of Fastly's JavaScript on Compute@Edge support. We have found it to be faster than QuickJS. The source code is here: https://github.com/fastly/js-compute-runtime.
2. Fastly Compute@Edge is built on wasmtime. You can develop web services for it in Rust, JS, and Go: https://developer.fastly.com/learning/compute/
3. Fastly's multi-tenant platform is closed source, but our single-tenant local development platform, which also uses wasmtime under the hood as well, is open source: https://github.com/fastly/viceroy. It isn't a big leap to make viceroy multi-tenant: Wasmtime provides everything you need, and all Viceroy would have to do is dispatch on e.g. HTTP host header to the correct tenant. Our multi-tenant platform is closed source because it is very specialized for use on Fastly's edge, not because the multi-tenant aspect is special.
Stay tuned, the next article in this series on Wasmtime security will run next Tuesday.