I started using WebAssembly in earnest a few months ago to make a backend auth library that works in several different languages[0]. It's built on Extism[1], which abstracts away some of the interfacing complexity. It's been an awesome experience. Frequently feels like magic.
WASM is in an interesting place. The value has clearly been proved with a pretty minimal core spec. Now there's a big push to implement a much larger API surface for WASI and the Component Model. A lot of people in the community are concerned about this direction, or at least the way it's happening[2].
For my part, I hope WASM doesn't go the way of the rest of web browsers where it gets so complicated that only big tech is capable of making implementations and experimenting.
I agree about what your concerns about complexity, but the way I see what we're
encapsulating is almost entirely essential. To draw analogies with native binaries:
- Wasm is a (virtual) instruction format for programs to be compiled into (think: x86).
- Wasm Components are a container format and type system that wrap Core Wasm instructions into typed, hermetic binaries and libraries (think: ELF).
- WASI is a reserved namespace for a collection of standardized Wasm component interfaces (think: POSIX header files).
To reach our goal of having shared, portable binaries that aren't locked into
any one vendor we need all three. A standard instruction set, standard calling
convention, and standard syscalls. Wasm Components and WASI might not be
necessarily be perfect, but at a minimum they're targeting the right scope. And that carries essential complexity.
I agree that some things are essential, and there's value in specifications. The question is how likely is the current tragectory to follow what happened with browsers? The major players are the same, which is concerning. Then there's early signs from the specs themselves. Why do we need wasi-sockets and wasi-http? Why not only specify wasi-sockets and let HTTP be implemented optionally by libraries for apps that need it?
Are there any forces in place to prevent the (de facto) mandatory API from becoming so complex that Google (or Fastly) is the only org capable of maintaining an implementation? Because that's how you end up in the situation where the "user agent" with majority market share starts gutting ad blockers.
I'm not saying I'm predicating this will happen with WASM or even think it's very likely. I don't know enough to have a real opinion on that. I'm just saying I really really don't want it to happen.
One of the maintainers of Extism here! Thank you for the kind words.
As you know, we're all about delivering value with the actual standards today. This means using truly portable, w3c Wasm core modules. Not some "maybe in the future" standard a la Components.
If you realistically want to use Wasm everywhere, in practically every language, Extism is the way to go and we're in it for the long haul.
For those who appreciate the WIT IDL being worked on (now for way too long), we support a far simpler, more familiar OpenAPI based version to eliminate the boilerplate of type conversion & serialization across the guest-host boundary, worth checking out: https://github.com/dylibso/xtp-bindgen
Thank you for Exstism. My main request is that you keep the core interface as simple and forkable as is feasible. You're certainly incentivized to make it as complicated as possible so only your team can maintain it, but I hope you're able to find a sustainable business model that doesn't go down that path.
I'd love to hear why WASM now has more promise than Java 1.x.
Java's subsequent development was driven by enterprise/containers (mainly Oracle), and the VM has stayed relevant for 30 years by incorporating dozens of advances in machine and programming models. Both successful and lamentable.
If WASM (i.e., the loose collection of organizations driving it) could do it better than Java, wouldn't Java (with all its resources and organization) have already done it?
The answer has to lie in unsustainable or limiting technical decisions. What exactly are the design decisions WASM made to make it seem like it would escape becoming Java-like?
Roughly the same reason as every time someone asks the same question in any post that mentions WASM: Java is a particular model with a particular view of the world, tied to a GC and a particular standard library and various hard limitations such as no user-defined value types that make it impossible to compile C code to properly and run it with reasonably C-like speed. Just because Java has incorporated dozens of 'advances' doesn't mean any of them address its longstanding problems, and you're mixing implementation tech with spec design in your reasoning. You, in your daily life, likely use zero software incorporating Java and multiple pieces of software incorporating WASM. You cannot imagine using Java for shaping functions embedded in font files, or sandboxed 'native' modules in a JS-based text editor, or blockchain smart contracts. In fact Java basically cannot be reliably sandboxed at all.
Because WASM is currently solving a real problem for me that Java can't solve, ie easily embedding code I wrote in one language into many other languages. You can do something similar with shared libraries, but you have to compile them for every architecture and OS and solve the associated distribution problems. Ask Python and JS how that works out in practice. A WASM artifact runs everywhere, and has addition security benefits.
Seems to have a lot more momentum though? I can run Haskell on WASM, and all the backends for JVM and CLR are long dead. More to the point, I can target the browser without plugins, lock-in, or security problems.
A couple of months ago we announced Hyperlight [1], a lightweight VMM that can spawn new VMs in about a millisecond.
Today we’re happy to announce the Hyperlight Wasm guest based on the Wasmtime runtime. This makes it possible to run Wasm Component binaries on top of WASI interfaces without the need for a guest OS in the VM. In this post we explain how this works and walk through an example.
Though both share the ability so securely execute multi-tenant workloads, but they make very different tradeoffs when it comes to compatibility vs performance. To compare:
Firecracker is great if you want to securely execute an OS image. It has the benefit of compatibility with many existing programs, but that comes at the cost of some overhead.
Hyperlight is great if you want to securely execute program runtimes. This requires bespoke guest bindings, but it has the benefit of having less overhead.
There’s a place for both approaches, and I see both happily co-exist.
From what I understand Hyperlight's boot process is more similar to a microcontroller than a PC (although it use your CPU architecture) - the VM directly boot into your code. Unlike Firecracker, Hyperlight VM doesn't have any hardware while Firecracker do have VirtIO devices, serial console and keyboard so that traditional operating systems can be adapted to Firecracker. Host-Guest communication is done with shared memory.
It depends on how which performance metrics you're interested in, where you draw the boundaries for individual workloads, and how you then schedule those workloads. Hyperlight can start new Wasm workloads so quickly that you might not need to keep any idling instances around ("scale to zero"). That's new, and it makes comparisons a little more complicated. For example:
- If we take VMs as our boundary and compare cold start times, Hyperlight confidently comes out on top. That's 1-2ms vs 125ms+.
- If we take warm instances and measure network latency for requests, Hyperlight will come out on top if deployed to a CDN node (physics!). But if both workloads run in the same data center performance will be a lot closer.
- Say we have a workload where we need to transmux a terabyte of video, and we care about doing that as quickly as possible. A native binary has access to native instructions that will almost certainly outperform pure-Wasm workloads.
I think about Hyperlight Wasm is as yet another tool in the toolbox. There are some things it's great at (cold-starts, portability, security) and some other things it isn't. At least, not yet. Whether it's a good fit for what you're doing will depend on what you're doing.
I'm really excite about this! I've got hopes that WASM/WASI will grow into the dream of the JVM from the 90s. A memory-safe target for development that allows easy of porting and testing across multiple platforms. WASM can, and hopefully will, be for so much more than browsers.
WASM isn't memory-safe through (no more than just having the application running in a separate process) because it doesn't type tag the memory. JVM was safe but that's also a serious disadvantage, because it bakes type system into the runtime system.
Why is 'more memory safe than just having the application running in a separate process' the benchmark? Literally nothing can clear that bar. It is more memory safe than most existing VM languages, which is all anyone actually cares about.
That’s the idea! This is at the heart of our upcoming Azure Front Door Edge Actions platform. Our CTO Mark Russinovich talked more about this at Ignite last fall:
A Wasm component running inside of Wasmtime is just fine. However, when you start to use resources from outside of Wasm, e.g. systems, network interfaces, GPUs, etc., Wasmtime uses OS resources from the host that it is running upon. If this host is running on your trusted compute base, then it implies you are trusting the host implementations in Wasmtime, which for some is just fine. However, Hyperlight-Wasm gives platform builders the ability to describe the interface between the guest and the host explicitly, so you could only expose the host functionality you would want with the trusted implementation you'd want. For example, if I'm building a FaaS, I may want to provide only an exported event handler and an imported key/value interface to the guest for which I've built a safe, multi-tenant implementation and strictly disallow all other host provided functionality.
Good question. I think it’s the additional security? From [1]:
> Hyperlight is able to create new VMs in one to two milliseconds. While this is still slower than using sandboxed runtimes like V8 or Wasmtime directly, with Hyperlight we can take those same runtimes and place them inside of a VM that provides additional protection in the event of a sandbox escape.
It's the same reasoning that leads people to move things from running in an OS process to running in a VM. In theory, it adds security and better isolation. Hyperlight appears to substantially reduce the overhead of running VMs which makes it more appealing as a target if this fits your needs and you want the isolation of VMs.
I suspect that Wasm on the web mostly just works and so we don't hear too much
about it. It is occasionally mentioned in passing though, usually as part of
another announcement. Well-known production users of Wasm on the web include
Dropbox [1], Adobe [2], Figma [3], and 1Password [4].
That reminds me of the time when Java applets had their high time.
I think that WASM in the browser will either largely replace JavaScript or will wither away like Java applets did. I fear there is no in-between and if it is only because no one will support two languages and ecosystems in parallel and in the long run. Not the big companies and certainly not the small ones.
How are instances started and managed? Via some API?
Can you give a Wasm Component binary the capability to execute a tree of connected Wasm Components, delegate capabilities, and manage their life cycle?
As for executing a tree of connected components, in the current state of Hyperlight-Wasm you'd probably want to take a collection of components and compose them together using something like https://github.com/bytecodealliance/wac to create a final component composed together from multiple components.
Thank you for the illuminating references! So this sockets example is a host that runs on a raw vm (x86_64-unknown-none target) and spawns sandboxes. To get at my original idea, I could imagine a sandbox with special functions imported from the host that can spawn new sandboxes. This could be complicated by the fact that spawning these sandboxes and hooking up inputs/outputs seems to be statically compiled...
I wondered how components were supposed to be used. So wac takes a group of wasm components and merges them into a new .wasm file with inputs/outputs mapped according to a defined .wac file. Then you can just run the new .wasm file. Does this not obviate the isolation benefits of having separate wasm modules? Is there a path to running a tree of components directly while maintaining the sandbox between them?
WASM is in an interesting place. The value has clearly been proved with a pretty minimal core spec. Now there's a big push to implement a much larger API surface for WASI and the Component Model. A lot of people in the community are concerned about this direction, or at least the way it's happening[2].
For my part, I hope WASM doesn't go the way of the rest of web browsers where it gets so complicated that only big tech is capable of making implementations and experimenting.
[0]: https://github.com/lastlogin-net/decent-auth
[1]: https://extism.org/
[2]: https://www.assemblyscript.org/standards-objections.html
- Wasm is a (virtual) instruction format for programs to be compiled into (think: x86).
- Wasm Components are a container format and type system that wrap Core Wasm instructions into typed, hermetic binaries and libraries (think: ELF).
- WASI is a reserved namespace for a collection of standardized Wasm component interfaces (think: POSIX header files).
To reach our goal of having shared, portable binaries that aren't locked into any one vendor we need all three. A standard instruction set, standard calling convention, and standard syscalls. Wasm Components and WASI might not be necessarily be perfect, but at a minimum they're targeting the right scope. And that carries essential complexity.
Are there any forces in place to prevent the (de facto) mandatory API from becoming so complex that Google (or Fastly) is the only org capable of maintaining an implementation? Because that's how you end up in the situation where the "user agent" with majority market share starts gutting ad blockers.
I'm not saying I'm predicating this will happen with WASM or even think it's very likely. I don't know enough to have a real opinion on that. I'm just saying I really really don't want it to happen.
This sounds like an OS like user space to run atop WASM similar to POSIX.
Standards are good but my hope is the design is well thought out.
As you know, we're all about delivering value with the actual standards today. This means using truly portable, w3c Wasm core modules. Not some "maybe in the future" standard a la Components.
If you realistically want to use Wasm everywhere, in practically every language, Extism is the way to go and we're in it for the long haul.
For those who appreciate the WIT IDL being worked on (now for way too long), we support a far simpler, more familiar OpenAPI based version to eliminate the boilerplate of type conversion & serialization across the guest-host boundary, worth checking out: https://github.com/dylibso/xtp-bindgen
Java's subsequent development was driven by enterprise/containers (mainly Oracle), and the VM has stayed relevant for 30 years by incorporating dozens of advances in machine and programming models. Both successful and lamentable.
If WASM (i.e., the loose collection of organizations driving it) could do it better than Java, wouldn't Java (with all its resources and organization) have already done it?
The answer has to lie in unsustainable or limiting technical decisions. What exactly are the design decisions WASM made to make it seem like it would escape becoming Java-like?
Today we’re happy to announce the Hyperlight Wasm guest based on the Wasmtime runtime. This makes it possible to run Wasm Component binaries on top of WASI interfaces without the need for a guest OS in the VM. In this post we explain how this works and walk through an example.
[1]: https://news.ycombinator.com/item?id=42078476
Firecracker is great if you want to securely execute an OS image. It has the benefit of compatibility with many existing programs, but that comes at the cost of some overhead.
Hyperlight is great if you want to securely execute program runtimes. This requires bespoke guest bindings, but it has the benefit of having less overhead.
There’s a place for both approaches, and I see both happily co-exist.
Deleted Comment
- If we take VMs as our boundary and compare cold start times, Hyperlight confidently comes out on top. That's 1-2ms vs 125ms+.
- If we take warm instances and measure network latency for requests, Hyperlight will come out on top if deployed to a CDN node (physics!). But if both workloads run in the same data center performance will be a lot closer.
- Say we have a workload where we need to transmux a terabyte of video, and we care about doing that as quickly as possible. A native binary has access to native instructions that will almost certainly outperform pure-Wasm workloads.
I think about Hyperlight Wasm is as yet another tool in the toolbox. There are some things it's great at (cold-starts, portability, security) and some other things it isn't. At least, not yet. Whether it's a good fit for what you're doing will depend on what you're doing.
https://youtu.be/EYCA0cR1dkI
> Hyperlight is able to create new VMs in one to two milliseconds. While this is still slower than using sandboxed runtimes like V8 or Wasmtime directly, with Hyperlight we can take those same runtimes and place them inside of a VM that provides additional protection in the event of a sandbox escape.
[1]: https://opensource.microsoft.com/blog/2024/11/07/introducing...
Maybe we should drop the Web from Web Assembly and call it something else?
[1]: https://dropbox.tech/tech/2018/06/building-better-compressio...
[2]: https://thenewstack.io/adobe-developers-use-webassembly-to-i...
[3]: https://www.figma.com/blog/webassembly-cut-figmas-load-time-...
[4]: https://blog.1password.com/passkey-crates
I think that WASM in the browser will either largely replace JavaScript or will wither away like Java applets did. I fear there is no in-between and if it is only because no one will support two languages and ecosystems in parallel and in the long run. Not the big companies and certainly not the small ones.
The world I see is one where WASM is a permanent second class citizen and probably already has reached its peak adoption.
Not that I hope for it, quite the contrary, but that is what it looks to me.
EDIT: crypto miners and fancy tech demos I should say
As I understand it this is designed to sit on bare metal and this is all a bit hamfisted but I don’t have a spare bare metal x86 around.
Guessing just throw this into a vm and accept that it’s nested virt?
Dead Comment
Can you give a Wasm Component binary the capability to execute a tree of connected Wasm Components, delegate capabilities, and manage their life cycle?
As for executing a tree of connected components, in the current state of Hyperlight-Wasm you'd probably want to take a collection of components and compose them together using something like https://github.com/bytecodealliance/wac to create a final component composed together from multiple components.
I wondered how components were supposed to be used. So wac takes a group of wasm components and merges them into a new .wasm file with inputs/outputs mapped according to a defined .wac file. Then you can just run the new .wasm file. Does this not obviate the isolation benefits of having separate wasm modules? Is there a path to running a tree of components directly while maintaining the sandbox between them?