On this page On this page
episode 24: WebAssembly and Rust in Practice, A Conversation with Alex Crichton.
In this episode we sit down with Alex Crichton to talk about WebAssembly and Rust in practice. We discuss how Wasm grew beyond the browser into a serious runtime for servers and plugins, and why Rust fits so well in this space.
We also explore WASI, the component model, and lessons from building Wasmtime, covering performance, security, and what it takes to run Wasm in production.
If you like this podcast you might also like our modular network framework in Rust: https://ramaproxy.org
00:00 Intro00:42 Introduction to Alex Crichton and His Journey04:14 Understanding WebAssembly: Basics and Benefits07:35 Challenges of WebAssembly and DOM Access16:29 Exploring WASI: The WebAssembly System Interface31:11 The Relationship Between WebAssembly and WASI34:43 Understanding WebAssembly Instructions37:09 The Role of Compilers in WebAssembly40:07 Exploring Roto and WebAssembly Integration42:19 Garbage Collection in WebAssembly44:17 Dynamic Libraries and Code Sharing in WebAssembly45:49 Core WebAssembly and Its Layers48:39 The Component Model's Evolution51:25 String Handling in WebAssembly54:26 Simplifying WebAssembly for Developers55:30 Specifications and Documentation in WebAssembly57:31 Asynchronous Support in the Component Model01:01:29 Exploring WASI P3 and Async Support01:10:36 More about the Component Model01:22:39 The Role of the Bytecode Alliance01:26:57 Akamai's Interest in WebAssembly01:31:29 Exploring WebAssembly Use Cases01:37:27 Future of WasmTime Development01:40:24 Understanding WasmTime's Architecture01:44:34 Getting Started with WasmTime01:51:19 Security and Testing in WasmTime01:56:11 Outro
Music for this episode was composed by Dj Mailbox. Listen to his music at https://on.soundcloud.com/4MRyPSNj8FZoVGpytj
Elizabeth (Plabayo BV)
0:13 | π
This is netstack.fm, your weekly podcast about networking, Rust and everything in between. You are listening to episode 24, recorded on January 21st, 2026, where we talk with Alex Crichton about WebAssembly and Rust in practice, with a focus on Wasm time, WASI and how these technologies work internally. Glen (Plabayo BV)
0:42 | π
Welcome everybody for a new week of Netstack.FM Today with me is Alex. Welcome Alex. Hi, thanks for having me. Glen (Plabayo BV)
0:51 | π
Yeah, I'm very happy to have you because as I was researching about web assembly and with who to talk to, you seemed like the perfect guest to me. So I'm very happy that you could make some time for us. Now, I think most in the Rust community might know you, but still we might not know your origin story. And I like people to know this kind of stories because it gives people often inspiration about how to get to a certain place in life or how to read something or... or you can see the different perspective, different origins. So yeah, go ahead. We would like to get to know you a better, Alex. Of course, but my origins date back, β if want to go really far back, started programming in like 2000 and something, I don't know, but no. My Rust and Wasm stuff all started in late 2012 when I was in college. I started contributing to the Rust compiler, started rewriting some stuff in Rust at that time. This was pre 1.0, the dark ages of Rust. And so I very quickly found some bugs and such, started contributing and it kind of snowballed from there. I got hired by Mozilla later that, or. The next year after that, this was after I had graduated. And so I worked on the Rust program in language primarily for about seven years. This was sort of the lead up to 1.0. I kind of was one of the primary authors of Cargo and Crates.io and the standard library, lots of compiler infrastructure, the release infrastructure, CI infrastructure, lots and lots of stuff. So I had my fingers in a lot of pots in the Rust community. So I worked a lot on Rust β post 1.0 as well. So like the async system, like Windows targets or proc macros and things like that. And then around 2017, 2018 is when I shifted to WebAssembly. So this is when WebAssembly was first released and the web browsers, this was the MVP kind of when it was all initially being released. And so at the time I was talking with my colleagues and I was like, man, would be perfect for WebAssembly. It's the exact poster child for what we're good at. So I started shifting a lot of my time to making the WebAssembly targets in Rust, kind of doing all that initial integration and then starting to get Rust to look very good on the web. So this was a WASM bindgen, we're kind of going along there. And then that shifted over time a little bit more to the outer browser works. This is kind of what I do nowadays personally, which is I primarily maintain the Wasm time, WebAssembly runtime. And I've been doing that for since like 2018, 2019 now at this point. Then over a couple of companies working a lot on Wazzie, the component model, the whole outer browser ecosystem and still just super interested in the whole WebAssembly space, the whole Rust space, of moving them with both of those forward, making sure that it's kind of, I everyone has a lot of dreams and ambitions for what Rust or WebAssembly can do, but. It takes a time to actually get there, to actually meet those expectations. So that's a little bit about me, at least from my background. Glen (Plabayo BV)
3:28 | π
Yeah, very cool. I mean, I love it. And yeah, I remember also from very early on in Rust, like WebAssembly was always a bit there. Then it kind of faded a bit into the background because first we indeed were thinking around the browser. And I remember then it faded to the background. Then after that... You started to hear about okay, you can run like wasn't workers like I know cloth layer or something like that They were some other companies which were only doing that But even that again moved a bit into the background, of course The real like contributors and companies who invest in it keep working on it but it came like a bit in in waves and β But still I don't feel the excitement ever stopped β Now, I don't think all of our listeners know about WebAssembly, so maybe we can begin our story by explaining a bit what exactly is WebAssembly. Yeah, definitely. So WebAssembly, as the name might imply, comes from the web. That was the initial genesis of where it is, but it's not web-specific in the sense there's lots of non-web use cases. the general idea of WebAssembly is a very low-level bytecode and container format, not like Linux containers, but more like kind of like an ELF executable of sorts. And this bytecode is intended to be portable and runnable across many different systems. So one example is web browsers. So you can take any WASM module and run it in a whole bunch of web browsers. pretty sure every modern web browser. And one of the chief properties of WebAssembly is, or two, I guess, are its speed and security. So WebAssembly is very well known for its sort of near native performance. The general idea is you'll probably get within 10, 15 % of performance, depending on the benchmark, depending on exactly what you're doing. But that's the rough ballpark, because it's not like three or four X slower than native performance had you compiled a native code. So that's the speed aspect. But the other major, major aspect of WebAssembly is the security story. to run anything on the web, that's just complete table stakes to have the complete, nice, secure sandbox. And WebAssembly is an extension of the JavaScript sandbox. so WebAssembly has very strict properties and very strict guarantees in terms of as a runner of WebAssembly, as the embedder, I get very strong guarantees of what the guest can do. And the guest knows what's gonna happen when it starts executing stuff. So for example, segfaults are not a thing, out of bounds memory accesses are not a thing, use after free is not a thing. in the sense of the host is protected. You can still have bugs in the WASM module itself, but this is what makes it so attractive as a platform for web browsers to host, for outer browsers like CDNs to host, is that it is such a nice secure sandbox. And then that has nice benefits for you as a developer in terms of debugging and such. If you blow up your sandbox, it's just the sandbox. You can make a new one and try again. But sorry, in general, the two high level points of WebAssembly are, I guess the three in a sense, are speed, and safety. All those three are kind of combined together in one. Glen (Plabayo BV)
6:24 | π
Yeah, I mean, very cool. mean, sometimes I hear people referring to it as the thing that Java promised us, but never was. Is that like a fair comparison or is it like kind of missing the boat? No, yeah, it's sort of slightly inaccurate, I would say, which the spirit of it is definitely correct. It's the whole like compile once run everywhere thing. The major difference between WebAssembly and Java, however, is Java has more of like a runtime aspect. So β it's got a big garbage collector. It's got lots of host APIs. It's got lots of built-in APIs you'd expect to use for programming, which is like arrays, reading files, printing the screen, things like that. WebAssembly has none of that. WebAssembly is more akin to like a safe CPU. By default, the fanciest thing WebAssembly could do is it can grow its memory. It's not quite malloc, it's more like an M map of sorts. But that's the idea. WebAssembly doesn't have any host. It can't print, it can't open files, it can't do anything. So that's the major difference between the JVM and Java style things and WebAssembly things. sort of yes, compile runs from anywhere, but sort of no in the sense of the JVM is a little bit more ambitious in terms of runtimey stuff or providing default runtimey stuff. Glen (Plabayo BV)
7:35 | π
Yeah, yeah, fair enough. so I got excited about WebAssembly long ago for the web. Also in that days I was still in the game industry and it was like, okay, we could run our games also in a web browser. That's pretty cool. β But then I got more into other kinds of web development on the site and there it kind of felt like a bummer in the sense. like it felt still a lot more easier and I feel it still today to just write some vanilla JavaScript if you want to like interact with the DOM if you want to use all these web APIs and I always wondered like why because essentially it feels like I don't think it would take them that much given how much resources browser companies have to expose these web APIs directly to the Wasm interface. So what am I missing there? Is it just because our attention now is fully on the non-browser use case and maybe for the browser what we have is enough because we expect that anything with web APIs, let them just do it with JavaScript, there's no need for it? Help me bit understand the situation there. man, that's a weighty question, but this is the million dollar question. In some sense, I could describe my entire career arc in WebAssembly going from Rust and Wasm all the way to Wasm time is actually defined by exactly this of getting access to DOM APIs in a sense, sort of. So β the general answer was yes, that is correct. You cannot access the DOM natively in WebAssembly. You have to go to JavaScript and then JavaScript accesses the DOM and this adds lots of overheads. adds... It adds overheads relative to doing it purely in JavaScript itself. So if you have a very DOM heavy workload, it's actually not, you are unlikely to see a benefit moving that into WebAssembly because of these sorts of overheads. So, okay, I'm gonna miss parts of this question. definitely hold me true to all the questions you had in there. But the first one, at least that I can remember is, β so why haven't browsers done this? So I don't work. Glen (Plabayo BV)
9:27 | π
You Personally, I haven't worked at Mozilla for some time now, so this is somewhat guessing, people can definitely correct me I'm wrong. But the general idea is I think that the majority of WebAssembly, kind of major WebAssembly users today, not like the majority, it's kind of like the big ones, the ones that like, know, dry revenue and all that good stuff, they're primarily using WebAssembly, I believe, for more kind of the optimization tasks, so not very DOM heavy things, not very kind of like... not porting like a JavaScript application purely to Wasm, but kind of like getting offloading the compute intensive parts of JavaScript to WebAssembly because it performs so much better. So in that sense, there's not really a ton of motivation to give WebAssembly a lot of native access to DOM APIs. Now, doesn't mean it shouldn't happen. Just means from like, that sort of perspective, it's not fully motivated quite just yet. But of course, there is a very large community developers. This is a very common question you'll see come up, which is why doesn't Wasm have DOM access? So there's another major aspect to that in my opinion, which is the question is like, how do you do it? Web assembly at a very fundamental level is core web assembly. What actually you talk to web browsers with, and it has four types. I guess, well, four initial types, which was I32, I64, F32 and F64. So integers and floats. Nowadays there are β V128 vectors. There's some GC objects as well. It's a little fancier, but in general, that's, it's sort of a very low level it's operating at. So. there hasn't historically been a nice way to say, let's actually take the DOM object and give it to WebAssembly. So nowadays it sort of exists, but you still have the problem of how do you represent a string? Like your language's representation of a string is probably different than what the web browser uses. Web browsers have like ropes and private implementations and all sorts of fancy stuff for all sorts of encodings. Whereas like in Rust, for example, it just a UTF-8 list of bytes. And there's just no question of like, that's the only way to represent a string or kind of the canonical way to represent a string. So that's another question to ask is how do you interact these two? So do you want the string to live in the host? Do you want the string to live in the guest? How do you convert? When do you convert? What's the cost of that conversion? All that fun stuff. So more or less what I'm getting at is that once you start giving a language like WebAssembly access to DOM APIs, there's all sorts of questions of GC management, life and management, string manipulation, string encoding, options encoding. Like you have... not just the DOM, but the entire web API surface area described in WebIDL. How do you map all of that to WebAssembly and then how do you map all of that to Rust? It turns out this is a really, really difficult problem, both in terms of just technical complexity, software complexity, but also from the embedder side of things. So we're describing a problem which is not super well motivated from like a money reason in a sense. I mean, I'm not controlling the web browser in that regard, but that's my impression. It's also extremely technically complicated. And also it's extremely high risk. Again, in the sense that browsers are relying on WebAssembly for a complete security sandbox, this is a major extension of that sandbox. So it would be a very, very large effort to implement all of this. And so it's even worse to want to scrutinize it very, very carefully. So effectively, this is all a giant major effort where today's escape hatch of just call it JavaScript and let it do it, let it do its thing. works fantastically well from a functionality perspective, not quite from a like integration perspective. And like there are major downsides to that. this is, you can't run Wasm on the web without JavaScript, which means you can't just write Rust and run on the web. Someone in that chain of developer tools, be it you or someone else has to know JavaScript, has to know how DOM works and all that fun stuff. that's sort of like the rough idea. Does that answer that part of the question? How's that sound? Glen (Plabayo BV)
13:15 | π
Yeah, yeah, totally. So, I mean, and in a way I think it's fair and open cause anyway, like modern JavaScript and CSS and HTML five, I I'm, I know it's not like popular opinion, but I like it a lot actually, like I can work in it, but where I do see value in, in, web assembly in the browser is, uh, and it's just my opinion is, is where you maybe have like something like a very interactive application or let's say something like this, where we have like, or I don't know, like a spreadsheet, things like that. and I imagine, and at that point you're just gonna work on a canvas or something like that. But there still might be some, and I think bringing up the DOM was a bit wrong with me because I get that super complex, but there are some other web APIs like, I don't know, like hardware access, like things like WebRTC, I don't know, like there are some more like smaller scoped web APIs, which I think... you might be able to bring in some kind of form to give direct access to WebAssembly and maybe that's good enough because those are also the things you anyway might want from like a Canvas application. also those you still need to go via JavaScript, right today, like with JSBindt stuff. Exactly. Exactly. This is actually a perfect segue in the sense that so the DOM problem is really hard. And this is what WasmBindgen initially was trying to solve. We wanted to get Rust working well on the web, how to do something with DOM, yadda yadda, all that fun stuff. So this was actually a genesis for, β I guess I should say, no. There have been a lot of proposals over time to solve this problem. This is not someone that has been, we haven't just ignored this problem where no one's thought about this or tried to do anything about it. But originally, a long, long time ago, this thing was called WebIDL bindings was the idea that it was a defined way that you would import WebIDL functions from the web into WebAssembly modules. This would handle all the things like GC and string encodings and all that. That was, so that would give you access to DOM, all these sorts of APIs, kind of even the Canvas APIs, everything a little bit you would want. That then morphed into interface types. This was kind of as we started to work on it, kind of did a little bit more, tried to answer some of these questions. And that started being a little bit more ambitious in terms of, we'll have a bit of a grammar. It's not quite tied to WebIDL exactly, but it turns out we had these outer browser use cases, which also wanted to deal with high level data types like strings, as opposed to only integers and bytes and things like that. And then that itself has actually now morphed into the component model and WSZ and all sorts of stuff in the outer browser ecosystem. And so the way I would describe it nowadays is that it's like my own personal arc in a sense is that the component model is in a sense, the answer here in terms of how we would give high level access in an embedded language like JavaScript to WebAssembly, to actually WebAssembly guests and languages and things like that. And so the rough idea, I mean, if we want to predict five or 10 years in the future, DOM access on the web is something that I would like to see or kind of helping to work to see is through the component models. This would be, I know I haven't talked too much about that. I'm sure we'll get to it. But the idea is like this current work was sort of. go from the web browser to outer browser space, it's kind what I've been working on, and then kind of make its way back into browsers where the component model provides these kind of first class accessors to the DOM and access and all that fun stuff. Sorry, that was a lot of information, but. Glen (Plabayo BV)
16:29 | π
Yeah, yeah, I mean, anyway, it's quite a big topic. β And our goal is also kind of like to bring some inspiration to the listeners because we will never be able to cover everything, but kind of like give a kind of overview of everything a bit. And then, you know, some things, guess we can go deeper. β So another reason why I'm nowadays interested in it is indeed for this out of browser experience where the promise would be that I can have some kind of host language like Rust and for example we maintain a network framework called Rama and so an interesting use case for us is that we could provide something like β a Wasm support crate such that people could write proxy middleware or some kind of things like that. in any language like let's say Go or β Rust, doesn't really matter, and compile it to Wasm and then do it. And in the past I wouldn't have known how to do it, but nowadays we have Wasi. And so I think it's nice we can introduce that a bit because I think it stands for WebAssembly System Interface. And how I understand it, because I only started like, I don't know, getting into it like some months ago, is you have some kind of contracts. Glen (Plabayo BV)
17:46 | π
and you can define for both the host and the... I'm not sure what it's called, the other one. You have the host and the other... Glen (Plabayo BV)
17:53 | π
the guest here, that makes sense I guess. Anyway, you have those things and you can define, okay, what does the guest have to bring? Like what do they have to implement? And what does the host facilitate you? And something else I really like is how you can have memory owned by one thing or memory owned by something else and it's quite nicely separated. So to me that feels like a very like powerful, I don't know, primitive. Glen (Plabayo BV)
18:19 | π
and a lot of like, yeah, would say potential, which for now not that many people know about. So I think I butchered what is Wazzy quite a lot. So I will let now you do a better job to explain it to someone who doesn't know at all what Wazzy is. no, no, no, you're all good. And so you've hit on another major use case for WebAssembly, which is plugins. So the idea to extend your application safely with a sandbox thing you don't have to worry too much about with WebAssembly. Because then the other aspect, guess, going back to the sort JVM, WASM thing, is β the JVM or Java in general has a big runtime. It's got lots of GC, lots of host APIs, all that big stuff. WebAssembly, however, is intended to have, or least be able to scale down to a much, much smaller runtime. We're talking hundreds of kilobytes in the smallest possible cases. So that's what makes it so suitable for the plugin style use case. However, this is where Wazzie comes in the picture. So let's say you want to write a plugin system. Well, it turns out you do actually still want to open files. You still want to talk about things like strings. You still want to print to the console every now and then to debug and things like that. And so while it is with core assembly, every single host of a plugin would have to make an entirely new way to print to the screen, to open a file, kind of a custom version. They would all look pretty similar. But additionally, Rust itself wouldn't necessarily have a target for every single one of these. It wouldn't have like an application A target, application B target, application C target. So this is where Wazzy comes in. Wazzy is a standards-led effort in the WebAssembly CG currently to basically say that here is a standard set of interfaces and APIs which languages, ecosystems, and bettors toolchain, everyone can agree upon. So the idea is that it provides canonical way to print to the screen, the canonical way to open a file, and then you as an embedder get to decide, well, I'm actually going to give it to you or I'm not going to give it to you, so you have to run without it, or if I give it to you, I can like give you access to files and all that fun stuff. So that's what enables Rust and Go and Python and Ruby and all sorts of languages to have targets so you can compile an application to Wasm and then you can actually run that everywhere because it has the same set of APIs that everyone is accessing and then all the runtimes agree that they have semantics of the APIs and all that. So that's kind of where Wazzy comes in. It's kind of also a component aspect in terms of like strings and records and types and all that fun stuff. But the Wazzy thing is primarily agreement on the standard set of APIs. And then Wazzy is kind of all about like sort of modularity too, or it's not just a monolithic set of every single API you could possibly want, but more of a kind of pick and choose. So maybe your embedding has like access to Wazzy NN or various like, you know, GPU style things or Wazzy Web GPU or things like that. But my embedding may not, maybe it only has files. Maybe it doesn't even have files kind of. in that aspect. Glen (Plabayo BV)
21:03 | π
Yeah, I I like it a lot because it should mean in theory that I can just compile the program β using like a Wasm compiler and it should just work right because if it adheres to the contracts, then it's supposed to be type-saver. I mean, of course, it could be like business logic books in there, but at least from like the type perspective and from the interface perspective, we know at least that should work. Whether they implement it correctly, that's of course a different matter. Glen (Plabayo BV)
21:33 | π
Yeah. Well, that's where the sandboxing comes in, think, you know, making it so it's nice and contained whenever it explodes. Glen (Plabayo BV)
21:39 | π
Yeah, yeah, for sure. And so... Yeah, kind of like the way I was thinking about this was like you would you would maybe have some kind of like pipeline where okay, first it needs to compile and secondly, you might have like a set of integration tests that it needs to like go through and if that succeed, maybe then you patch like the new version or something wouldn't wouldn't catch everything. But yeah, I mean, it's still better than nothing and it's quite powerful, I would say. And one thing I was concerned about was okay, let's say, for example, I have some kind of HTTP middleware like Glen (Plabayo BV)
22:11 | π
want to allocate the entire β body into the guest language. But then I noticed you can actually stream nowadays in WebAssembly via WASI. Or did I misunderstand that? No, you're definitely correct. This is for the sort of outer browser use case, some major use cases, proxies, exactly what you describing earlier and kind of like WASM is the orchestration between how do these endpoints all connect to each other. So, and that's performance and streaming and optimizing all that has been definitely forefront of everyone's mind and designing all these APIs. Glen (Plabayo BV)
22:45 | π
Yeah, I mean, I like it a lot because there was indeed already like an API for a lot of HTTP stuff or like a WASI contract. mean, how should I call these things? Specification? I suppose we're mostly calling them interf- well, it kind of depends exactly what you're talking about, but yeah, contract interfaces specification, kind of all similar-ish. The literal terminology in the textual description, which is sort of the source of truth, is interface, and interface is a collection of functions. But then we also talk about things that are called worlds, which is sort of like the stuff you can import and the stuff you must export. So, but that also is very similar to a contract, so 6 to 1 half thousand together. Glen (Plabayo BV)
23:23 | π
Yeah, yeah. I mean, I remember those words because, yeah, I first found the WebAssembly website and then I also found the Wasi website and it has like a very nice book. And I fully read it and I liked it a lot. Is that also the of the part or learning part you recommend to someone who's new to it? Like to first go through those resources or what you recommend? Yes, definitely. β I think it's wasy.dev will link to the Component Model Book, which is hosted in the Bytecode Alliance, which is a set of companies working on the Component Model and how to browse this stuff. That's a great resource to get started on the Component Model. And then think Wazzy in general. then webassembly.org is the main web assembly website. It's got a whole bunch of resources for just kind of learning a little bit more about Wasm, Core Wasm, the web use case, and things like that. Glen (Plabayo BV)
24:09 | π
And like after that, I would think someone can just start playing with something like Wasm time and start using it or, or they're, yeah, I mean, in a way it's old and new at the same time. Like in the end, all these things are like having already in development for so long, but still I feel resource wise, is there already like a lot of like books or things people might want to pick up that they could like study further or is not necessary or what you think. That's a really good question. I know there are some books coming out. I think I was just reading one the other day. so there are definitely books in WebAssembly. There are definitely books for the outer browser WebAssembly space. β It's one where WebAssembly ecosystem has sort of been evolving, albeit a little bit slowly from time to time, but it has been evolving over the past seven or eight or so years. And so β if you find resources from 2018, They're probably a little dated and may not be quite so applicable today. So the dates, I'm not trying to have a minimize in that sort of date aspect, otherwise no, definitely a lot of books, online tutorials and like blogs and things, they exist. They again, might be a little dated, might be slightly inaccurate in terms of like maybe the idioms have shifted over time, but stuff in general should more or less still work and sort of the main thrust of everything should definitely be there. Although. I will say this is one where I've, least in my own personal opinion, I think β the excitement around WebAssembly has not been quite matched by the development energy around WebAssembly. So I have found those often expectation of more kind of fully formed, fully fleshed out and very well laid out documentation when it's not quite there just yet. So, you know, some things might be there, some things might not be there, but we're working on it. Glen (Plabayo BV)
25:51 | π
Yeah, understand. I I certainly like it and it got me very excited. And what I did notice is like there are some interface like HTTP, like those you find in your GitHub repositories, but then some they don't exist yet, such as like I think around WebSocket and similar protocols, which I also would like to have an interface for. Like how easy is for someone like me, which is still an outsider, to β propose such an interface. and start pushing that forward. Like what would be required and what's the process. Definitely, yeah. So this falls under the purview of the WASMCG subgroup, which is sort of part of the WASMCG. So like the official process for this would be you would join the WASMCG, which is mostly just telling someone your email and you get added to a list. You might have to have a company affiliation. I'm not entirely sure about the W3C policies, but anyway, it's intended to be very lightweight. And then from there, you join the WASMCG subgroup, which is mostly just saying I'm interested in. And then you would go through that process. There's sort of a very similar phase process to changes in WebAssembly itself, where it goes through discrete phases of this is a proposal, this has some interest, this has some like concrete designs, it has some like testing implementations, it kind of gets more more over time. β I will say however though, β adding a new Wazee proposal is kind of a heavy weight. not heavyweight, it's a significant process. So it's not something I would recommend necessarily for first-time contributors to kind of someone just add it to the space. Now, I don't want to dissuade anyone obviously, but it's a bit of a big deal in the sense that it's of socially the expectation is so you can make a WSI interface totally just fine. But there's a contract on both guests and hosts at that point in the sense that guests are expected to sort of implement libraries in terms of this interface. So for example, let's say we added Wazzy WebSockets, or yeah, then we would have to go to the WebSocket libraries in Rust and add Wazzy specific stuff to say, okay, instead of whatever you're doing on native, let's go do the Wazzy WebSocket thing instead. But then additionally, would be in expectation of hosts. So you would want the dis-implemented in runtimes like WasmTime or in platform providers that host WasmTime or kind of have their own WasmRuntime. So there's a lot of folks to get agreement amongst in that space. it's kind of, it's not quite as easy as just proposing something, but it's kind of getting consensus and agreement amongst the stakeholders. Now, I mean, I'm heavily biased towards the β CDN style, like server style β browser use case, but there are folks, for example, that are proposing like a WSI USB or WSI for various kind of like IoT style devices. And so. that has a whole different set of like stakeholders and contributors and such. And so it's a little bit different. So it kind of depends exactly on the shape of the proposal, but it's kind of one where like you could propose new DOM APIs. That's a big process. TC39 is like, it's a whole process and thing. And I'm sure anyone can do it, but it's a lot of β upfront investment to kind of get something like that through there. Glen (Plabayo BV)
28:53 | π
Yeah, I mean, I get it. And so the first use case was still definitely be HTTP. And my goal would be to try to stick as closely as possible to the HTTP interface they find already because it seems pretty neat. And then maybe that could be a first contribution where I maybe do find something that might be able to use improvement. Maybe I could start with that. And then my next goal would be I want to implement something new. We would first do it in our own framework. We would already test it, try to refine it. And then maybe that could serve as a base for like a proposal and at least so that the ball is rolling there because like I'm sure we cannot be the only framework that is used for proxies and other kind of network components that does things about these kind of like protocols. β Yeah. Glen (Plabayo BV)
29:39 | π
And I would think it's nice that because yeah, I don't mind doing it all like just, okay, we keep it contained and we have all these interfaces versus WebSocket maybe then in the future something else because there are plenty of like network protocols. But of course it would be a bit sad if like, if someone writes plugins and they first use this kind of proxy, then that kind of proxy that then you kind of like need to implement entirely different interfaces. So that's where the standard interfaces play a nice role, I suppose. Exactly. this is actually a kind of a, an interesting thing that's also worth talking about, which is that, so if you expect that you kind of pick up a crate off the shelf and Rust and you want it to be integrated with Wazzy, that's a good candidate for a Wazzy proposal. Kind of stuff on crates.io that you're not like, is not tied to anyone particular embedding or server or anything like that. That's fantastic for Wazzy. So this is like HTTP as an example, printing sockets, all that fun stuff, However, Wazzy does have affordances for if you do have a embedding specific thing or Wazzy less so more component model like, but if your embedding has a very specific API that kind of only makes sense for your embedding and maybe like your SDK for Rust would provide access to it. β There are definitely affordances for that. That's kind of where APIs can start where like you would start having maybe a custom API. If Wazzy doesn't cover those use cases, you'd have it there. And then over time, if you have, if there are actually more, for kind of taking this and using it elsewhere. That's where kind of the WSZ part comes in where it makes more sense to kind of shift there from a vendor specific API to a WSZ specific API. Glen (Plabayo BV)
31:11 | π
Okay. And so if we, if we, if we go back a bit and so now we kind of like know WebAssembly and Wazzy, like how tightly are they tied together? Like, like can one, I mean, I imagine Wazzy cannot go without WebAssembly, but can, can, can WebAssembly have a future without Wazzy? Like, like I want to know kind of like the relationship and how tight they are together. Very good questions. And I think these are some sense of the world evolving. It depends on who you talk to for the exact answer. So I'll give you my answer at least, but yeah. So we have core WebAssembly at the very base level. This is what web browsers run. This is not going away. This is going to be the foundation for everything, where it wasn't Layered on top of that is what I keep talking about the component model. I think we'll talk more about that actually, but the idea of the component model. So this is a layer around WebAssembly, which is not talking about WSZ yet. This is sort of giving us the ability to talk about strings and records and lists and all that fun stuff. So kind of a layering, but also it kind of allows you to β link modules together. So WebAssembly modules, you can link them together, but they're not quite as composable from like a just plug in together. have to be very, they're very specialized in terms of ABI. Components give you sort of the types and also the ability to link things together very easily and compose applications together. So that's the component model. Layer on top of WebAssembly and the component model can't exist without WebAssembly. They're very tied at the hip. then layered on top of the component model is where Wazzy comes in. So Wazzy is defined in terms of types that the component model gives you access to. So Wazzy has an F32 type, but this is actually somewhat distinct from the β F32 type in WebAssembly because for example, there's, I guess I should say integers, so it's the I32, but there's also in Wazzy β signed 8-bit integers, unsigned 8-bit editors, all that fun stuff. So these don't exist in WebAssembly as native types. but they do exist in the type description of the component model itself. So in that sense, WASI is very heavily dependent on the component model, which is dependent on WebAssembly. Now there's with a lot of interest, however, that WASI, or no, sorry, the component model's type descriptions, it's sort of its WIT IDL, the way you describe types without implementations, is β not just applicable to WebAssembly. This is something that you can see in other systems or not. It's not, I think, actively deployed there, but it could make sense. It's similar-ish to like Thrift or protobuf or capnproto or things like that. There's, mean, similar-ish. It's not the exact same as those. It's trying to solve the exact same problem. So there might be a, not necessarily a future, but a use case for the component model and sort of those widths, types and things like that outside of WebAssembly. But definitely the main focus today is almost exclusively on the WebAssembly aspect. Glen (Plabayo BV)
33:49 | π
Yeah, that makes sense. And so as you hint at yourself, like we already talked a lot about the WebAssembly core thing, as far as I know is mostly about, you have your your base CPU instructions. And so for example, I read about β extended or improved SMD support that would be in that core WebAssembly because that's still your instructions. Glen (Plabayo BV)
34:13 | π
β and you keep mentioning β CPU and of course more and more we also program GPUs and it used to be via shaders but then we had other languages to do that and but I guess that would be more in the realm of web GPU. There's no future where that would like merge with WebAssembly I guess. Yeah, most likely. I think there are various projects to try and get WebAssembly running on GPUs, but I know so little about GPUs, so I'm just going to mislead everyone. So I'm going to stop at that. Glen (Plabayo BV)
34:43 | π
Yeah, I mean, that's fair enough. so as you said yourself, like WebAssembly is very primitive. Can we kind of like summarize kind of like what it exactly expose? I mean, not like I don't want to like list you all the instructions, but like maybe like in groups, like kind of like the high level, I don't know, categories and groups and things like that, just to have a better understanding of that. Definitely. And so I would say, kind of, the major categories of WASM instructions. So one is numerics. These are things like just add two numbers, divide two numbers, test if two numbers are less than each other, what a is less than b, stuff like that. You can then mirror a lot of those for floats. So lots of floating point instructions, division, multiplication, NANDs, all that fun stuff. SIMD is kind of numerics as well. It's just kind of a wider thing. So it has more. So then you also have a ton of instructions related to memory. So these are loads and stores for memory. This is kind of like a risk V style architecture, kind of a risky thing. And then the other two, I guess the other major category would be control flow. So WebAssembly has things like branching, loops, blocks, call instructions to go somewhere else. There's exceptional stuff. like a tri block or tri table, think it's called. Things like there are throws and throw instructions for exceptions. So that's sort of like the low level aspect. It is actually surprisingly close to what you would think of like a Like take a risk ISA for a CPU and then make it fully sandboxable and you more or less get WebAssembly. Glen (Plabayo BV)
36:10 | π
Okay, and so how can I... Yeah, how do I have to picture it like like that because okay you have something like a wasm time Is the the the wasm runtime that you help to develop and maintain? Like how does it go from from that kind of I would say like emulator or how you call it like like a state machine going through your instructions to then the actual Let's say hardware instruction CPU instruction. Is it like a pretty one-to-one mapping or is it like? Still something more clever going on there. this is the fun world of compilers. my God, I love talking about compilers. I love working and talking about compilers. But okay, yeah, so like the first job is your WebAssembly compiler has to take your language and then spit out WebAssembly. That's, β LLVM is kind of the main workhorse nowadays for producing LLVM code, or sorry, Wasm code. Now, right, the problem of how do you go from Wasm to native code? There's a whole lot of options here. One option is you don't, you actually just interpret it. So there's a whole slew of WebAssembly interpreters that just kind of interpret the bytecode and things like that. But even once you go to compilation, there's actually multiple ways that you can do things. And kind of the main two things you can do are kind categorized as, one is there's a baseline compilers. These are typically, they look at an opcode, they do exactly what you just say. They just splat out a whole bunch of native instructions for each opcode. The exact same native instructions almost every single time, maybe modulus and register differences. But the idea is that baseline compilers are simplistic in their... complexity in terms of they just run over the bytecode once and they just splat out a bunch of machine code and that's it, they're done. They walk out of the picture. That tends to not be very optimized because a lot of WebAssembly semantics needs are kind of... The bytecode is not designed to be run directly. It's designed to be run through an optimizing compiler. So the baseline compiler will generate some optimal code. You typically get maybe 100 % slowdown compared to native. It kind of depends on the code. The main thing that most production WebAssembly compilers do is they go through another full compiler. So you ingest WebAssembly, you run that through a full-fledged compiler, not LLVM, but kind of a full-fledged JIT compiler. So in a while's time, we use Cranelift. SpiderMonkey would be using, or sorry, Firefox would be using SpiderMonkey, Chrome is using V8, and they have various tiers inside there. But the idea is you take all the WebAssembly bytecode, you convert it to a compiler IR, You do a bunch of optimizations on that. like constant propagation, various things all out there. And then you have a very optimized machine code lowering. So you have a lot of rules for kind of taking these constants in various places, fusing them all together into a single x86 instruction, all that fun stuff. So more or less the answer to your question is compilers, fancy compilers all along the way for all these various stages. And that is how we go from WebAssembly to actual native machine instructions that we're running on a CPU. Glen (Plabayo BV)
39:00 | π
So does that mean if I use some kind of runtime like Wasm time and I load a Wasm, what do call it, plugin or whatever you call it, it does all that and then I end up with a big blob of, let's say, unsafe code? Is that basically what I can high level picture it? That's what I have in the end. And because I know I have the contract, like the Wasi contract, I can just know, okay, I can call this function or I to give this kind of data structure all because of, yeah. Glen (Plabayo BV)
39:29 | π
Okay, that's very cool and I didn't know I was using Crane Lift. That's what he said, right? He uses Crane Lift for the Wasm time. Okay, that's very cool. That is how we actually generate the machine instructions. And from what you're describing, it's sort of we trust Cranelift that provided untrusted WebAssembly, it produces trusted output. So WebAssembly we know it can always be untrusted, anyone can give it to us, but it has very strict semantic guarantees. So the trusted output of Cranelift is what we run. And it is all it's using machine instructions, which are highly unsafe or can be highly unsafe. But that's general trust there is we trust the train look compiler for that. Glen (Plabayo BV)
40:06 | π
Okay, yeah, because that part reminds me of like episode 14 where we had like β NL Netlabs. I don't know if you know those people, but they make Roto. Have you heard of Roto before? yeah. you know, I feel like I have, but you should definitely remind me because I... Glen (Plabayo BV)
40:23 | π
Yeah, so I mean, I like Roto a lot as well because I did a lot of things like Lua in the past and all kind of scripting languages. And as far as I understand Roto, but you might want to talk to Terp directly because he's the one developing it, is that it also takes in your Roto scripts and it also uses CrayonLift as far as I to do something similar to compile it down to then your machine code and it runs super fast. And because they use it for their own Glen (Plabayo BV)
40:53 | π
like network related components and That one I also find very interesting. So I want to have both like Wasm support in our framework as well as as Roto because they have both their own use cases. If you don't mind learning a new scripting language and I think Roto is super cool because like in a way a lot simpler. But if you want to go from any kind of language because maybe your team already knows Python or Ruby or Go, then it might be much nicer to be able to develop like in your language and compile it to Wasm. So, but it's very interesting to me. Glen (Plabayo BV)
41:27 | π
I didn't know this so thank you for that that it like wasn't time like and and Roto there have like a lot of similarities. That's very cool It's true. But what you're describing there is actually one of the major benefits of WebAssembly as well, is get the theories, you get to bring your own language. Now, languages have varying degrees of WebAssembly support, but that's the dream is that you don't have to, a, it's a bit of a kind of like meta level concern, but it's like as a platform provider who is taking WebAssembly modules and running them. you don't have to dictate the language that all your users use. They all get to do whatever they want and they give you as a binary. And so it's kind of a nice decoupling of that concern. Cause that's been, that has plagued a lot of platform providers in the past as forcing teams to use one specific tool. And that creates a lot of friction and a lot of problems and sometimes at least. Glen (Plabayo BV)
42:19 | π
Yeah, yeah, for sure. in that context, β is it already here or is it coming? But there is lot of noise about the garbage collector, the GC. Like, is that already now there? And if so, where does that live? Is that in the component model? I suppose it is there then? Or where would that live? Okay. No, actually, this is all pure core Wasm. So you're definitely correct. This is the WasmGC extension and it's got lots of support in core Wasm. So this is primarily supported in web browsers. And I believe that there's a slew of languages that do compile to it. So these are things like, believe Dart, I think OCaml, I think a variant of Java that it's, there's some like subset of Java that's used in Google for online stuff. It's that subset. It's not like full Java. I forget exactly which though. Glen (Plabayo BV)
43:04 | π
Okay. But the idea is, yes, so that's all using WasmGC nice and fast because of that. WasmTime also supports WasmGC. However, languages like Go or Python or Ruby or even JavaScript, they can't natively use the WasmGC. They have to use their own runtime and things like that still. So WasmGC is suitable for some languages to be used directly, but not necessarily for every single language. Glen (Plabayo BV)
43:27 | π
Okay, so you're saying that if I'm writing a plugin in Go, it has to bring its own GC. I mean, how big of a size is a typical Go plugin? That must be pretty big then, or am I overestimating it? It's true, yes. This is one where, for example, writing a... I don't think you could... You probably are not going to write a couple hundred kilobytes of a Go application and deploy that over the web. It might totally be possible, but my impression is that, yes, language like Go has to bring its runtime with it, and that typically means the WASM binaries themselves are a megabyte or two in size. Glen (Plabayo BV)
44:03 | π
And is there a way for these kind of different plugins to share codes, kind like a dynamic library? Like, would you have like one, I don't know, go GC thing and then all of them use the same thing or how, I mean, is that a thing? This is a fantastic question. The answer is yes. So this is one we very much wanted to design for this in the component model, which is core wasm itself doesn't deal so much with kind of linking and dynamic libraries. Like you can do it. You can do all of it, but it's sort of, it's not prescribed at the core wasm layer. However, at the component model layer, we kind of want to make all these things first class. And so for example, we actually do have it working today where you can compile Python, like lib Python to a .iso, which is actually just a .wasm thing. We just have the same name. Glen (Plabayo BV)
44:20 | π
you And then you use that. your application kind of lives as a separate core Wasm module, which then links to the Python.iso. And then what you can do is you can actually take that out. So you can have a whole bunch of components that'll import Python to the actual library so that their components themselves don't even contain Python, but they import it. And then you as a platform provider could actually provide Python as a service. You can say, this is the Python binary that I'm providing, which is Python 3.12 or whatever version it currently supports. As a platform provider, can share all that machine code. And as users, you don't have to deploy and send to Python interpreter every time you upload your uploader as a module. Glen (Plabayo BV)
45:21 | π
Okay, okay, very interesting. I mean, I want to get into that a bit, but now I'm also a bit confused because so far I thought, okay, WebAssembly Core is just about you have your core, meaning like your instructions, but now you're also telling me it also has modules like GC. So that means that even Wasm Core is kind of like layers, right? Like how many layer or is it like, I don't know. It feels layered now, am I wrong? That's true. I think it was catching me lying or I'm misleading you. So this is definitely on my end, but no, so the core Wasm specification doesn't quite have fully specified layerings today. Now there's a lot of desire for that. So for example, there is a specification for core WebAssembly and it has GC and you can't take GC out of it. It just has GC. However, it's pretty common that β Wasm, there are... It's common for Wasm runtimes to implement subsets of the specifications. So for example, they implement all the numerics, but they don't implement GC. So not quite layering in that sense, but it's still layering sort of the metaphorical sense of a sorts. But yes, a very fundamental unit of Core WebAssembly is the module. You produce a module and that contains functions and all sorts of stuff inside there. And so those modules can be linked together. You can do all sorts of stuff with multiple modules on the JavaScript API side of things and all that fun stuff. And then the component model sort of wraps around that and makes it, provides a standard format by which to link core modules together. Whereas currently on the web with core modules, you have to use JavaScript and just a whole bunch of like wiring things up for core modules otherwise. Glen (Plabayo BV)
46:59 | π
Okay, okay. And so we also already learned that you can do like streaming, but that's part of components. So that's not in there. But what about something like, something like a sync things, like if you want to do a sync operations or like, is that something that's on part of core? I mean, is that even possible or is it part of components? That one is definitely a complete amount of layered things. This is sort of like your CPU is gonna have, well, okay, I don't know. The CPU analogy does break down because your CPU doesn't have a garbage collector. So I'll sort of gloss over that. That's sort of a sort of, if you want to write a safe sandboxed instruction set, you have to specify that the garbage collector is like on the host because otherwise it's just not safe or it's not interoperable. so. Glen (Plabayo BV)
47:32 | π
Yeah, that's why I got confused. from the CPU, you, I'm gonna randomly say that WASM is a CPU versus like it has GC or not, but in this case, if WASM is a CPU, your CPU does not have async instructions. Your CPU has syscall instructions to do various operations that your kernel will like move between threads or your runtime will move between threads. So what I'm getting at more or less is that at the Kompana model layer, you would describe an interface at a high level sense like, yes, this is an async function. And then the component model specifies the ABI for how exactly that works. So for example, I call you and you say, oh, I'm not ready yet. I don't have my answer. me back later. Kind of like a Rust style poll function in a sense. And so that's the way where the component model assigns ABI semantics, which are implemented in terms of Core WebAssembly. And then that's how it all ends up lining up. So async is implemented with Core Wasm. And so that way you can model it in languages like Rust, but it is not natively supported in Core Wasm. It's kind of more of a higher level concern to that respect. Glen (Plabayo BV)
48:48 | π
Okay, and so now to start getting a bit into the component model, like to begin, like I don't think I was there in the beginning, right? Like I imagine first you had just because yeah, okay. And then at what point did it get introduced and why? Correct. This actually goes back to, it was the DOM. It was the DOM problem. We wanted to solve the DOM questions as well. So this was originally, it was called WebIDL bindings. And that was way long ago when wanted to just DOM things. And it became interface types and then it became module linking. And then I think it went back to interface types. And now it's back to the Komodo model. So the Komodo model was, I think around 2019, 2020-ish. And that was when we realized that if we wanted to run WebAssembly modules outside of a web browser, it's just sort of table stakes. need something like the component model because otherwise every runtime everywhere is going to invent its own way to represent strings, lists, all sorts of things. And we needed a standard way to do that. So that was the genesis of the component model. So most of the development of the component model has been primarily focused on the outer browser style use case. So these are server side, WASM time, all that fun stuff. And that's mostly it's done completely out of necessity or well, a large part out of necessity where In a web browser, you've got JavaScript that can do all sorts of stuff, and it's just sort of how you interact with WebAssembly. But out of a browser, you don't have JavaScript. You've got WebAssembly runtime, but the host is the, like, you can't configure how the host is touching your module. Like, that's part of what the embedder does. So anyway, that's motivation for the component model. But that's sort of where all those types came from, that motivation of kind of making it usable out of a browser without having to have an extra embedding language around WebAssembly like the web has The component model is intended to go back into web browsers at some point. So the development trajectory has currently been focused on the outer browser use case, but we've always designed things and developed things with the intentions of eventually putting this in web browsers natively at some point. Glen (Plabayo BV)
50:31 | π
Okay, Okay, big dreams, would I like it? I mean, yeah, sure, why not? But just to make it clear, as let's say a Wasm user, I can basically just think of Wasm Core and Wasm Components as one black box that my runtime provides and I don't really have to, I mean, it's not like I can just add my own components, right? We try to dream big. Correct. Yeah. This is one where it's like a compiled target. in the Rust world, example, Wasm32-wasmp1 will generate a core Wasm module and Wasm32-wasyp2 will generate a component. Glen (Plabayo BV)
51:27 | π
Okay, interesting, very nice. And so how do I have to then imagine it? Like, let's say you mentioned something like UTF-8 strings. Is it then like a single component? β It's a single definition. So like the component model system has a type called string, and then when you say that I'm exporting a function, or rather say you're importing a function that takes a string, like I'm calling console.log, so when I give it a string I have to give it a thing, and the component model defines what is the ABI for that string, which is I pass you a pointer and a length, and then you also tell me the encoding. So there's a couple different encodings that are supported, UTF-8, UTF-16, and then the runtime will then decode that and do whatever it wants with the string. So the runtime knows what you gave it, and then the runtime does whatever is necessary and suitable for that. Glen (Plabayo BV)
52:20 | π
Okay, is there still a use case of UTF-16? Yeah, definitely, JavaScript. mean, JavaScript has like UTF-16 and I think ASCII, Latin 1 style stuff, but yes, there's a lot of languages that have native UTF-16 support and their strings are just simply defined as UTF-16. So like a JavaScript string, don't quote me on this, I'm not JavaScript expert, but I believe it's a sequence of 16 bit characters with some hand waving around like, what they called? Glen (Plabayo BV)
52:27 | π
Okay. What's the, it's the Unicode clusters. It's the surrogates, unpaired surrogates, something that will hang around that. But sorry, yes. There are a lot of browser languages like Go and Rust and Python and such will primarily use UTF-8, but there's pretty heavy use cases for UTF-16 as well. Glen (Plabayo BV)
52:55 | π
Okay. Okay, and so let, okay, so I'm trying to understand because I imagine if I'm just trying to define some primitive type or some primitive instructions, get that that's probably, I can just do that because it's just in scope, kind of like your prelude or whatever you would call it. But how would I use these things like a string? Is it just also always in scope and I can just use them or I have to do some kind of import? Like how does that work? This is sort of the, what you're touching on sort of the layering of how do you take a language specific like a Rust string and then represent that in Core WebAssembly and then how do you represent that additionally with the component model string and how do you like, how do get all that hooked up and lined up. And the way this generally works out is by Nix generators. So β the component model has a format called WIT, which stands for Wasm Interface Types. It's just kind of a textual thing which says that this is an API that takes a string. It's kind of like a header file of a sort. Anyway, so from WIT, we use a tool called WITBindgen, which generates a bunch of Rust code, which then glues all the stuff together. So for example, there's no primitive component model string type in Rust, even on the Wasm32, WasmP2 targets. That doesn't exist. However, you generate APIs that take Rust level strings and then it does the thing to pass component model level strings out. So basically it handles all the ABI details for you. It kind of converts everything as necessary. So for strings, no, or for Rust, there's no conversions necessary because strings are already a pointer to length and we just pass that along. Glen (Plabayo BV)
54:43 | π
Okay, I get it. So again, it's not something you a user really think about. I mean, you might want to understand it, but it's not like something day to day you really have to understand. Yeah, it's a bit of an irony here where it's sort of, if Wasm is successful, no one will have any idea they're using it. But it's still required all of this work to get everything working, to get to the point that everyone doesn't have to worry about it. There's a lot of infrastructure to build out. So it's a lot of what we have been focusing on over the past few years is all of the infrastructure necessary that you as a sort of average developer. I mean, I'm not calling you an average teller, but any person coming into the Wasm ecosystem would basically, they don't have to worry about that. They don't have to worry about the binding generators, the API shapes, the ABIs, all that fun stuff. These are all details you obviously can get into. You obviously can play around with. I could call Linux syscalls manually, but generally I just go call the libc function instead. That's kind of like the shape of what we're going towards is building all the infrastructure that you don't have to worry too much about. It's kind of all behind the scenes. Glen (Plabayo BV)
55:47 | π
Okay, and so all of these are these also all specified like in one single spec or is it like kind of like all of them have like different kind of like RFC style specs like how do I have to imagine that? Like all these components like is it like Is their own specification or is just like they are all like in the same blob of specification? rate. No, that's a really good point. And this is one where, so, WASI and WASOM and the component model, those all have, to varying degrees of formality, specifications. I say that in a sense that core WASOM is formally verified. The component model and WASI are more textually specced right now. They don't have an actual formal model just quite just yet. However, everything else does not have formal specifications. So, wit-bindgen does not. Wit is included. in the component model, so does have a specification, but WIP-Bindgen does not. The Rust integration with WIP-Bindgen does not have a formal specification, none of that. The general idea there is that specs are very good for kind of like low-level details, like you're probably not reading like a web IDL to see like what your JavaScript can do, but you're going to like MDN to see like what APIs and documentation examples and things like that. So this is where the component model book from the bytecode alliance comes in, that's sort of the introductory documentation focused on like you and your language, these are the tools that you'll be using. And you can kind of go from there to kind of learn more about various tools. But the intention is that each language ecosystem will sort of maintain its own documentation as necessary to connect between whatever the language does to core Wasm to code complement model and kind of say how all that works out. Glen (Plabayo BV)
57:32 | π
Okay, and then if we focus a bit on asynchronous support, what kind of model is implemented in your component model and how would it relate, for example, to how features work in Rust? Exactly. So this is where I mentioned a little bit earlier this WASM32 WASI P1 target and Rust and P2. is sort of P1 was like the original version of WASI, quite old at this point, focused on core WASM was kind of the initial step. P2 was where components came in the picture. And what I'm going to talk about now is called P3. So this is the next version of the component model, which I should say WASI, same component model, just WASI stuff as well. So we're iterating on the component model specification over time, adding more features, various ABI definitions, things like that. And one of the primary things that we're focused on over the past year or two adding is async support. So this is async support in the component model as part of WSI P3. That itself has its own ABI's details there and exactly how it all works out. But to answer your question directly, β that perfectly well integrates with Rust features. So the idea being that when you run wit-bindgen, which is the thing that generates a bunch of Rust code from wit definitions, the wit definition is going to say async func, like it'll have an actual async function. And then the bindings you generate in Rust will actually be a async fn in Rust. And so it all integrates very, very well with the Rust feature system. And the idea is that for any language, you use async things in your language, whatever async flavor you do, and you go and run with that. So for example, β if you call, if you're in Go and you call an async function that conventionally will block your Go routine but allow other Go routines to run. So if you wanted to do it in parallel, you'd spawn two Go routines calling two host functions and things like that. And that's the rough vision for like what Go would look like in contrast to Rust, which has a totally different story for async. Glen (Plabayo BV)
59:32 | π
Yeah, and that's kind of like where I'm a bit confused how it works, but maybe it's similar. I think, β because in Go I get it because you just have like, you have like a global, like, I mean, as a Go developer, you don't have to think about it because you can just, as you said, you can spell Go routines with the Go keyword and it just works. And it's the same in many other languages, but like in Rust, okay, you have like, you have this concept of asynchronous. And so most people might be using Tokio, but you also have others. So I kind of like wonder, like, let's say I'm running my application, it's all running like in Tokio and I have all my tasks and they're running and I want to run now from my host language which is also like using Tokio runtime. Like how do I make it that my WebAssembly script, so the guest language is not blocking and it's just hooking into this runtime. I mean, not like explicitly but still like it should just be part of a task, right? Like how does that work then? I'm probably missing something very simple, but I have a hard time mapping it. Alex Crichton
1:00:32 | π
No, no, no, you're totally fine. mean, this is a fantastic question and it drives at the exact heart of like why implementing WASI and WASM time is kind of a non-trivial task. So I would reframe your question though to kind of, you're talking about languages like Tokio or Go or kind of like these guests in that regard or kind of arbitrary async runtimes, but you can simplify it to say that that's not what the host is seeing. As the host, when you're running these WASM guests, you're getting a WASM component. that imports some APIs and that's it. And so we can actually reduce your question to β kind of two halves. One is what are these API, or I guess one half is given these APIs, how do you actually implement the guest? And then the other half is given those APIs, how do you run the host? So these APIs are the Waze APIs, and this is sort of the async functions there and all that fun stuff. So one half of your question is, if you implemented a Rust guest, would the Rust guest be using Tokio? And answer is, It could. Right now it probably can't in the sense that I'm talking about this P3 target where Tokio itself does not have support for either P2 or P3. And so you wouldn't actually be using Tokio today. But another aspect is sort of like for the component model, sorry, there's a lot of facets to this. So you could definitely pause me. I could fill out more things as well. But β the Waze P3 aspects, so your each guest does not need to bring its own entire runtime. So you wouldn't necessarily need Tokio to run on top of Wazip3. This is where there's a little bit of a runtime there to kind of translate between like component model async and futures level async, but that's not as heavyweight or as kind of full featured as the Tokio runtime, for example. Like the component model is giving you the ability to spawn blocking or spawn threads or things like that. So first part there is in your situation, someone would have already figured out how to compile Tokio. implemented in terms of Wazee APIs. And this is probably like Wazee P3 Async and things like that. So the general answer to question is that when Tokio decides to block, it has some fundamental function which says, I am waiting on a whole list of events. Simply block me until one of those becomes ready. This is IACP on Windows. This is E-Poll on Linux. This is KQ on Mac OS, all that fun stuff. So that has some component model equivalent, and that's what Tokio will be using on Wazee. Now the host side of things, that's where things get really interesting, where we have these host functions that are, they want to block, the guest wants to be blocked, but you're exactly right, you do not want to block the host thread. And so this is where we have async support in Wasmtime where, I'm sorry, it's just kind async turtles all the way down. But the idea, I guess I should say we have fiber support. So we support the ability to suspend WebAssembly exactly as is, kind of saving its stack off on the side, and then return back to the host. So Wasm time has a very strict guarantee that it provides, which is that sort of from the safety security sandboxing perspective, it's not just Wasm, but it's also WSZ. And so it Wasm time provides the guarantee that your guest will not block the thread of β execution unless you yourself do it as the host API. So all of the fundamental implementations don't block the thread. They'll handle this via stack switching as appropriate, kind of all that fun stuff. Glen (Plabayo BV)
1:03:50 | π
very interesting I mean because Yeah, I understand now a bit better, at least from the, mean, if I'm calling from the host, a guest, like a function provided by the guest. like, let's say I have a, because is that like the world? don't know, like, I know the guest needs to provide certain functions, right? And so I can call it from the host. that's the easy one, I guess, because I can just call it and I'm, I, it's a sync, I can just await on it. And so that will just use whatever runtime I'm using. Alex Crichton
1:04:11 | π
Yeah. Yes. Yeah. Glen (Plabayo BV)
1:04:24 | π
That's the easy one, but I'm still a bit confused about the other direction. If I'm calling from the... but I guess in the end doesn't matter because... Is it also like the... Is the callers problem in Wasm a thing? So those... Can you only call an async thing from an async thing? Alex Crichton
1:04:46 | π
that's a bit of a nuanced answer to that question. The answer is sort of not. The rough idea is that function colors kind of don't exist in the component model async. To quite that same degree, they do exist to some degree. But I guess the way I would phrase it though is it's kind of all boiling down to stack switching. So. β If I'm in Rust, in a Rust guest, and I'm calling an imported function that is implemented by a Go guest, but Go implements async totally differently than Rust because it just like blocks in various places, the component model specifies how that works out, which is more or less stack switching, where when Go will block, it's actually going to suspend its stack and return control flow back to Rust to say Go is not ready yet. Glen (Plabayo BV)
1:05:37 | π
And that's also how it then works for the Rust, guess. Let's actually just go through an example. Let's say I'm calling a function. mean, in the end, it has to start with the host calling a function from the guest, right? Because in the end, it's the host running the guest. So the host is calling some function. And then that's... And so you're saying like it's possible that I'm calling a function which is not async, so just a synchronous function. But then that function that is defined by the guest language is calling back into the host language, which is async. then my question is how does that work? Like how can it then somehow still be non-blocking from the... Yeah, from within that Tokio task, let's say, because I'm running the, I called the initial entry point or whatever you want to call it. I call the initial entry function from β like a non-async function because it is not calling. So yeah, I'm trying to understand how is that then possible to not be blocking at that point. Alex Crichton
1:06:49 | π
Yeah, so this is where β my description of function colors sort of not being a thing in the component model is actually not true for Rust as the host function colors totally exist. So the answer to question is that would actually be disallowed. the if Glen (Plabayo BV)
1:07:05 | π
Okay, yeah then I guess my question is solved. Alex Crichton
1:07:09 | π
Yeah, yeah, it's sort of the easy answer of the host cannot synchronously invoke WebAssembly. The host is required to asynchronously invoke WebAssembly because WebAssembly could call an async host function and that has to show up as async on the caller side. Glen (Plabayo BV)
1:07:26 | π
Okay, but is it like, is it always or is it like just because of the text that somewhere there's a branch that's in a sink? Alex Crichton
1:07:34 | π
This is the kind of what we're settling on in Wasm time, which this has been a little bit in flux recently, but if WebAssembly could call an async function, the host must invoke it as async. And when I say async here, I mean like the Rust level async. However, if the WebAssembly cannot call a Rust async function, and this is done via like not static analysis, but just if there's any async, anything async defined. So if there's nothing async, you can call sync. So effectively, if you don't add any WSG APIs, you can call synchronous punch just fine. Glen (Plabayo BV)
1:08:03 | π
Okay. So it's not about branching, like checking your branch, it's just about like a pretty, like, like just checking if there's anything you think regardless if it's possible to call it or not. Alex Crichton
1:08:17 | π
Exactly. You can kind of think of it as like if the component imports an async rest function, you gotta call it async. But if the component does not import an async rest function, you can call it however you want. Glen (Plabayo BV)
1:08:30 | π
I I like it. I mean it's simple but to me it makes sense because anyway it's anyway pretty hard to predict everything perfect anyway like this yeah okay okay well that's a very simple answer to something I thought was much more complicated I love it Alex Crichton
1:08:39 | π
Exactly. β No, we, β I coming from designing a lot of the foundational stuff for async and rust, and then doing it sort of again for the component model. God, everything gets so complicated. You, you, gotta, you gotta keep everything as simple as possible. Cause otherwise there's no way to rationalize. Cause no matter how like, like, okay, this is a simple answer, but the implications you're still running into of like all these other sorts of interleavings and questions and async and hosts and how it all plays together. You still have to answer all those sorts of really complicated situations. And so that's sort of the guiding principle is try and make the foundations as simple as possible. So all these complicated situations, you at least can find an answer to is the hope. Glen (Plabayo BV)
1:09:31 | π
Okay, okay. And so, okay, very cool. And so let's say I'm running in production, like a cluster of proxies and I allow via some like trusted alternative, like, okay, people have to authenticate or whatever. Like I don't accept any connections. Like, let's say I know for sure the connection is coming from like a trusted source and it's giving me a new like plugin, but I guess I will always expect already like a WASM plugin, right? It's not like people are gonna send me like a go. program and I compiled the fly to wasm to then compile it to with wasm time to something like I imagine that I would probably want to expect already a wasm file. Alex Crichton
1:10:11 | π
Yeah, I mean you could provide compilation as a service, more or less, yes, you will accept WASM files which users have already compiled. Glen (Plabayo BV)
1:10:19 | π
Yeah, because otherwise, I mean, for example, there's nothing in Wasm time that would help me with that, right? Because like that would mean I need to bring my own compiler for every language I want to support. Yeah, I mean, that makes totally sense. So that's fair enough. And then... Alex Crichton
1:10:29 | π
Exactly, yeah. Glen (Plabayo BV)
1:10:36 | π
β Okay so if you go back a bit to the component model we already discussed it as all these things like the strings like β the async support. Can we maybe get like an overview of like what's in the component model? Alex Crichton
1:10:52 | π
Yeah, definitely. So the component model I was saying earlier is a layer around core WASM. So it's a new compilation target, but internally it's mostly core WASM modules. It's just some glue around the outside and some ABI definitions. So the component model is focused on the same sort of tight security sandbox that WebAssembly has. So for example, given a component, you have a very strict guarantee that it only calls things through exports or through imports, and you can only call things through exports with no shared memory. And then components are very focused on composability, where you can take two components and link them up together if their type signatures align and everything. So you can kind of implement. This provides use cases like virtualization or libraries as components, of fun things like that. And then internally, components are basically sort of a binary description of kind of instantiating Core WebAssembly modules, linking them up and instantiating more Core WebAssembly modules, things like that. And then from a type perspective, β components provide a type grammar. This is kind of through wit and interfaces and worlds and all that about how different components can interact. this defines both how two components interact with each other, but also how the host interacts with components. And all the types include all the signed and unsigned integer widths. So eight bits to 64 bits, floats, strings, characters, lists, lists of arbitrary types, not just lists of bytes, but lists of, you could have a list of list of string. β And then more recently, or I guess there's that, there's also the algebraic data types. So these are records, which are structs and rust. These are variants, which are edums and rust. There are edums in the component model, which are more like β kind of an edum and rust that doesn't have a payload. So like an Erno kind of thing. β What's the other one? tuples. And then apart from that, then there's β the async-related thing. So we have a future of... so like a future of anything, a stream of T, so kind of like an async iterator of a sort. Yeah, that's sort of the type grammar at least of components. Glen (Plabayo BV)
1:12:55 | π
Okay, and then if I want to have things like, let's say, time support, then we already want layer extra because then we are in the Wazilayer, right? Alex Crichton
1:13:07 | π
Exactly. There are interfaces in WSIE, these are like WSIE-cooled clocks where you can get a wall clock, a monotonic clock, a system clock, and they define that, for example, β instant in time is defined as a record which has seconds and nanoseconds or something like that. Very similar to C. Glen (Plabayo BV)
1:13:24 | π
Okay, very cool. So given all this, what is there something that I might not yet understand about the component model, but which is pretty important for me to understand as a user, like not so long implementing a runtime or implementing β language support, but more like as a user. Are there some things that are not obvious from the start, but that I really need to know? Alex Crichton
1:13:49 | π
That's a really good question. And yeah, so I tend to be a bit of a pessimistic person. So I'll actually focus on some of the limitations because it's not all like perfectly rosy. You can't take everything in the world and compile it to components. And so I'll describe some of those, which are like kind of important level setting for kind of users of components. So one is that components are very strict, what we call shared nothing boundary. So once you make a component, you can't share memory with it. You can't reach inside and pull out a string or things like that. You can only talk to it through component model interfaces. So that's just sort of a, there's not like an escape hatch in that regard. It's intended to be a security boundary of you can't actually poke holes in that. And then the other one is the sort of portability and compilation aspect of that. The fundamental language of a component is component model types, which predominantly have WSZ interfaces and things like that. which is not Linux. There is no syscall function. There's no Linux syscall function or things like that. So you can't take a library off the shelf and compile it necessarily. So a lot might compile, but if anything is using a Linux specific or Windows specific API, it's not going to compile to WebAssembly because it's not defined in terms of a WASI API. And perhaps one of the largest limitations we have currently is threads. So there's no parallelism in the component model currently. That's designing a fully sandboxed, fully safe system with threads is extremely difficult. Just look at web workers on the web, it's taken them a long time and it still has a bit of a ways to go. So that's something we're looking to kind of resolve in the P3 timeframe to at least bring cooperative threads or kind of like cooperatively multitasking threads where you can explicitly switch between threads. So it'll give you P threads, but you still won't have parallelism. β So the component model right now is not suitable for internally parallel workloads. So like if you critically rely on Rayon to paralyze everything, that probably won't be a great fit for components at this time. Glen (Plabayo BV)
1:15:55 | π
but I mean let's say if I'm Tokio Multithreaded then I guess I don't need to care about it because it's already like parallel where it needs to be parallel I Alex Crichton
1:16:06 | π
Yeah, depends on what you... So in the guest, no, because if you rely on the multi-threading in the guest, not going to work out. But we do have plenty of parallelism with the host layer, where yes, you can β serve a whole number of HTTP requests all the exact same time. They can all have their own Wasm instances and all that fun stuff. Glen (Plabayo BV)
1:16:25 | π
Yeah, yeah. And of course what I mean is like even from the host I could provide like as my world interface or however you call it. is it, mean, do I call all that world or what is it? mean, Alex Crichton
1:16:37 | π
We call it, so in WIT, there's an interface and a world. A world is kind of a description of a component and an interface is a description of a set of functions you import from the So more or less, you would import an interface from the host and then the host gives you a world because it's kind of the set of imports it gives you and a set of exports that it expects. Glen (Plabayo BV)
1:16:58 | π
Okay, so then I was correct. So in my world, I can define a function and the guest calls it and given that it's asking support, I mean, I can easily bridge then those two threads with like a channel or something. mean, okay, I'm saying a bit wrong. What I mean is like, it is possible that my host function like spawns a new thread from let's say rusts. Alex Crichton
1:17:26 | π
correct. Glen (Plabayo BV)
1:17:27 | π
and it then binds them with a channel and so the guest is just waiting on something asynchronously and so it's still doing like parallelism but it doesn't do it themselves but it's just because of the host is providing it behind the scenes. Alex Crichton
1:17:43 | π
Exactly. And that's just kind of like the host gets to always gets to do whatever it wants and has host powers. And I'll take this segue for a moment and say like this, this for me is one of the primary reasons of why we have developed Wasm time in Rust is that the host gets to do whatever it wants. so even if WebAssembly is safe, and even if the runtime you're using is safe and correct, you as the embedder still have to also have everything safe and correct. And so this is actually a fantastic use case for Rust, which showcases its strengths of You get the freedom to spawn threads, use Tokio and do everything you want and you don't have to worry about it. It's all going to be nice, totally safe and no side faults and everything like that. Glen (Plabayo BV)
1:18:20 | π
Yeah, I get a bit biased because I mostly see it as like a plugin thing and then then from that perspective I I sometimes think like when is enough enough because like I mean in a way besides maybe like missing Standardization around like was interfaces. I would almost say like I'm pretty happy with this like if you will retire and and and and this is what it is β Alex Crichton
1:18:45 | π
Yeah Glen (Plabayo BV)
1:18:46 | π
I mean, I don't need that many more features I would think for... because I would actually like to keep these plugins anyway pretty simple where I would just expect, okay, one thing provides just one function or two function or whatever it needs, but like the logic will anyway be pretty contained. But I suppose that speaks for my bias because some people might want to have entire programs. Like let's say instead of using a doc container, they might want to run an entire application within some kind of, yeah, like, I don't know, host layer, whatever. And I get that point you do need all these features that are still in flux and in development and in theory. Alex Crichton
1:19:29 | π
It's true, yeah. There's a lot of folks interested in Wasm and everyone you talk to will have a totally different use case of how they want to use Wasm. And so it's been trying to cater to all of this. But this is something we're also heavily focused on as well. kind of we have Wasy P1, 2, and soon 3. And our intention is Wasy P3 is sort of the final version. We'll kind of enhance Wasy P3 along the way, but in terms of like paradigms and shifts like... Wazip1 to Wazip2 was components. That was where we decided we need the component model and we developed the component model. Wazip2 to Wazip3 is, all right, we really need async and so we add async, but we don't expect there to be another similar shift. And so we want to release the component model 1.0 in the relatively near future after that. And similar with Wazip as well, and all defined in terms of component 1.0 style types and things. That's intended to be the basis by which to grow. So no risk of us retiring anytime soon. We definitely have a hard work cut out for us in that regard. Glen (Plabayo BV)
1:20:27 | π
I mean, yeah, I'm sure there's always work enough for that. just mean like I don't need, yeah, I don't need that many more features, I would think like in at least in the course pack, but it seems that that that you're kind of like aligned on that. But I imagine it will always be more improved as possible for sure. Alex Crichton
1:20:36 | π
Yeah. yeah, don't worry, there's always going to be more proposals for more things. Even just like, I mean, from a core Wasm perspective, you could imagine SIMD. So there's a subset of SIMD instructions currently available that is not going to cover all possible SIMD you could want. Like for example, it doesn't have 16 bit floats or anything related to that in core Wasm. So that's going to inevitably show up in core Wasm at some point. Component model stuff is always going to be extended. So these are always intended to be living specifications, but... We were still kind of trying to get to the point where we can say like, all right, this is the basis from which we will forever build upon the sort of eternal 1.0 that like, for example, Rust has. We're still working to get there. We'll get there though. Glen (Plabayo BV)
1:21:29 | π
But even then would you also kind of like have some kind of like edition system where you would have like, okay I can still do some kind of breaking changes just because like I can compile from my newer edition to my older edition as well like kind of like like polyfill like what I miss. Alex Crichton
1:21:46 | π
In a sense, yeah, we do have, I would classify that as more of like use the hammer to break the glass kind of moment. So we do have some of those in the component model where for example, we've specified an ABI, we call it the canonical ABI of when you lift and lower functions, say define core wasm and connect that to component model style stuff. We could define a totally different ABI and. they can coexist in the same module. So as long as the type grammar is still the same, we just have different ABI's and that hosts have different responsibilities and things like that. So we can do that. It's a big hammer to do. And so we don't want to quite hit that quite just yet. We want to avoid hitting that if we can. So the goal is kind of be more of a layered on style approach. And so we do sort of have the possibility of Rust level additions, but it's a bit of a different stability space than Rust in that respect. Glen (Plabayo BV)
1:22:39 | π
Okay and so a topic we didn't touch on yet is like the byte alliance and I don't recall that name and maybe I just forgotten but I don't recall hearing about it when I initially discovered like WebAssembly like in its early beginnings when I was very excited about it and And even for many other different reasons because at that time I was even thinking might be a nice way for like, because I also often teach people and I was thinking might be a nice way to introduce to web people how β assembly works because... I mean, I find it pretty like nice to do some low level programs in assembly. I well, actually I used to find it nice in like old, I mean, now I'm really dating myself, like, I don't know. I sometimes do miss those older days. I mean, not because it was better, but more. Alex Crichton
1:23:26 | π
Yeah Glen (Plabayo BV)
1:23:34 | π
it was like simpler, which of course also is on drawbacks, but at least I was able to understand all the instructions. like right now, if I look at a modern CPU, I'm like, okay, what the hell? They are like way too many instructions here. so, and so like, yeah, that's how I got into WebAssembly first because I found out, okay, that's very nice. I could, like, let's say someone knows JavaScript, they are pretty clever people and, and, and they can, they probably, I mean, not that you have to be super clever, but like it's, it might be a nice way to let it Alex Crichton
1:23:44 | π
Yeah. I know what you mean. Glen (Plabayo BV)
1:24:04 | π
to do something like that because they could program something simple and it could actually run in a browser and like it's it seemed very nice for that but yeah actually I got into a tandem my initial question was kind of like I don't remember the byte alliance like at that point was what did it already exist in the beginning like how did it kind of start Alex Crichton
1:24:22 | π
Yeah, no, definitely. The Bytecode Alliance did not exist when WebAssembly first came out. That was the browsers, all the major web browsers and major browser vendors doing that. The Bytecode Alliance was created a couple of years later when β basically Wazzie started becoming a thing, where the Bytecode Alliance is a consortium of companies that all work together to make us a secure runtime and, sorry. assist the development of secure runtimes and tooling and ecosystem things and basically it's kind of a place for corporations to come and work together and kind of make a shared set of tools, shared set of guidelines, have shared maintainership and things like that. for example, Wasm time is developed within the bytecode alliance. There's various tools like Wasm tools, which is sort of a CLI for working with Bazin modules also in the bytecode alliance. But for example, specifications are not developed in the Bytecode Alliance. The Bytecode Alliance is not a standards-based organization. So that's all left for the W3C. The WebAssembly org on GitHub has all the WSSE standards and things like that, where the Bytecode Alliance is very heavily involved in developing those, but it is not solely responsible. It is not responsible for them. It is just a set of participants in that. So no, you didn't miss anything that did not exist when WebAssembly came out. I think it was 2019 or 2020 when the Bytecode Alliance was created. Glen (Plabayo BV)
1:25:43 | π
Okay, yeah, at that point I was again like I lost track of AppAssembly. But yeah, but who is part of the Byta Alliance? Alex Crichton
1:25:49 | π
Yeah, that's fair. I'd sue. You know, the membership change is enough. I believe if you go to bytecodealliance.org, there's definitely a list there. But the names that I can remember off the top of my head. So the companies that I know of are, so I personally work for Akamai. I've got colleagues at F5 and Fastly. I used to work for a startup called Fermion that was a member of the bytecode alliance. I believe Microsoft is a member of the bytecode alliance. There's a large suite of folks that are sort of a little bit more kind of the embedded systems related. And they're also in the Bytecode Alliance. think Amazon's in the Bytecode Alliance. I think Google used to be. not sure if they currently are. So it's kind of a, intent, it does have a lot of heavy hitters in the industry and various organizations. It represents this basically the set of stakeholders very interested in WebAssembly and its development. not necessarily exclusively from the browser space, also very much including the outer browser space as well. I think Mozilla obviously is the bike alliance, I believe. Glen (Plabayo BV)
1:26:59 | π
Yeah, I mean, I would think so. And like you said yourself that right now, I mean, you work for various companies, β all in function of like WebAssembly. And right now you're at Akamai. Like, why is Akamai interested in this? Alex Crichton
1:27:14 | π
This is one, so the startup I was working for, Fermion, was very recently acquired by Akamai. And Akamai is very interested in basically building out the sort of β WebAssembly functions service style service. So this is a pretty common thing. like Fastly has this offering, β which is that basically for every HTTP request you receive, you can run a WebAssembly function over that request. You can do all sorts of custom routing, custom matching, custom, whatever logic you want. That's the dream of WebAssembly. And you can sort of think of it, I mean, I'm I'm like somewhat separated to a degree, but for example, CloudFlare workers is a very important product of that they have, or least I'm pretty sure. Sorry, I'm not very much, I'm much more on the open source and standard Z side of things, but Akamai functions is intended to be sort of along those lines and that style of functionality sort of you can bring your custom logic, run your custom logic in a very efficient fashion, all that good stuff. Glen (Plabayo BV)
1:28:10 | π
Yeah, that's kind of like what people use lambdas for but then instead of like having a lambda you would have like it in like a bottom file basically. Alex Crichton
1:28:19 | π
Yeah, and think the main thing that CDNs provide is the, like, lambdas are run inside of, like, AWS data centers, and the idea is that CDN's got more servers in more places, and so it kind of reduces the latency in that respect. So it's kind of bringing, because the WASM file is lightweight, secure, sandboxed, and everything, kind of bring that closer to the user, like user as in the person doing the HTTP request, like visiting a website, as opposed to centralizing all of it inside of one big computation powerhouse. So this is in contrast to like containers. Like you could in theory provide containers, but containers are much more heavyweight and also not quite as, containers are not a security sandbox in the same way that WebAssembly is. Glen (Plabayo BV)
1:29:03 | π
and then like Fermion, I remember that company. I mean, they provided like some kind of runtime or something to basically run these kind of functions, no? Alex Crichton
1:29:17 | π
Exactly. So Fermion was the primary developer and maintainer of spin, which is a runtime that is implemented on top of Wasmtime, but kind of provides a little bit more of an opinionated set, kind of like a default set of APIs. has lots of tools for building WebAssembly modules, it's got SDKs for various languages. It's intended to be sort of a comprehensive development experience where you can like test modules, run modules, run them on the server as a development tool. Or Wasmtime, for example, is a kind of lower level tool where it's you figure out how to give me the WASM module and I'll run that. And SPIN also provides more APIs that are not necessarily standardized. So for example, a SQL API or like a GPU API. So they provide obviously the like the Fermion namespace or the SPIN namespace. it's not, it's not, don't mistake it as a standard, but the idea is it still gives you access to kind of the data functionality your platform has. Glen (Plabayo BV)
1:30:09 | π
Okay, yeah, mean, Spin I remember and it still seems to be open source today as well. I could just still today I could run my own Spin thing and run like I could just have like my own VPN or bare metal server and run Spin on it and start hosting my services. Alex Crichton
1:30:15 | π
But yeah. Definitely, yeah, that is definitely a use case intended and spin is definitely still in active development. I think I just sent a PR the other day to update my time. Glen (Plabayo BV)
1:30:41 | π
Okay but it's no longer because you said Fermion was then bought by Akamai is pinned and still maintained by the same people or is it now like now there are various other people nothing to do with Fermion or Akamai? β Alex Crichton
1:30:58 | π
No, no, so it's definitely still maintained by, β I guess, ex-Fermion, now Akamai employees. And itself is a, I believe, a project in the CNCF. And so I think it's got other maintainers as well. yeah, no, Akamai and the Fermion folks that are at Akamai all plan on continuing to maintain Spin. So a very, very major use case for us. Glen (Plabayo BV)
1:31:19 | π
okay very cool because β yeah i mean that that that got me excited the second time and now i'm excited the third time because yeah yeah because like Alex Crichton
1:31:26 | π
Nice. I'm glad I couldn't still the excitement on you. Glen (Plabayo BV)
1:31:34 | π
I mean, it's because I learned the different sides of WebAssembly and its use cases. Like I said, my initial use case was like, like I don't want to write JavaScript. I would like to just be able to write my native code and compile it into the web browser. Okay, that didn't turn out to be very nice. And... In the meanwhile, actually anyway, CSS and HTML and actually it's pretty nice as it is and where I do need it's not like JavaScript is all that bad, given how little I use it. actually I got into accept it. Not sure what that says about me. maybe, anyway. Yeah. And then, and then I got into it. Okay. Maybe I can, this is nice because I can, instead of using containers, I can just use this. Alex Crichton
1:32:13 | π
I know the feeling. Glen (Plabayo BV)
1:32:23 | π
But then now I can see it now I'm more exploring it and liking it more from the side as plugins because I can just provide interface and now I kind of like because it's very nice because let's say I have a proxy or some kind of gateway that the goal is then now I can just people to write the rules dynamically and update on the fly. And that means if these rules need to change, don't need to redeploy these things. in fact, that would allow me to run these services basically forever. Because at some point the core becomes kind of stable, but what still changes often is the rules. like, yeah, I mean, I'm not sure if I'm the only one, but I like it when I process it like a very long time to live. Alex Crichton
1:32:56 | π
Exactly. Mm-hmm. Glen (Plabayo BV)
1:33:10 | π
especially on bare metal, I find it very beautiful if something is like an uptime of more than a year or something. So I can cheat my way into that by letting it, by using WASM plugins because I can still update things but I don't need to restart, which is pretty nice. β Alex Crichton
1:33:18 | π
I know what you mean. It's true. That is definitely the dream. it's one we've seen, like, least what I feel like I've seen is any service that provides configurability, inevitably, if it's used long enough, people are going to want a Turing complete language to configure it. That's kind of where the Wasm plugin for configuration comes in, in a sense. Glen (Plabayo BV)
1:33:50 | π
Yeah, yeah, I mean anyway, I think it's it makes more sense because And this is kind of like a tangent, but like for so, so, so really long ago, long, long, long ago, I was writing PHP and, and, and in, in those days, and we were just writing PHP files, but then in line, you would like generate your HTML. And, I'll, actually like I had forgotten until some months ago how much I really liked that, because in the end where you do need the power of like a regular language, well, it doesn't matter because you Alex Crichton
1:34:04 | π
man. Mm-hmm. Glen (Plabayo BV)
1:34:24 | π
already in PHP and so it was very nice and then for the longest time kind of like I just had forgotten about that and we were just using templates but your templates kind of become like some kind of Frankenstein because you are just trying to emulate a real language because you want for loops and if branch and this and that and it looks pretty ugly but you can like accept it and like I literally just forgot about my PHP days and then and I try so many different templates over the years like template language Alex Crichton
1:34:26 | π
Mm-hmm. Yeah. my god. Glen (Plabayo BV)
1:34:54 | π
languages and all these different approaches. And then only recently I pivoted back to then just generating like HTML directly from Rust and then using some kind of like either just because I'm using Rust and I'm generating it or if it's simple enough or I'm using some kind of macro to then like do that. And to me that makes a lot more sense because I mean clearly I just want the language and clearly I want something server-side and so to me that makes total sense and that's same for those rules. Alex Crichton
1:35:12 | π
Mm-hmm. Glen (Plabayo BV)
1:35:24 | π
because like you said, eventually you start to have like YAML or JSON rules or whatever it is and they just start to look like languages but it's so awkward and so ugly and so hacky and then like yeah it makes much more sense to just write them in an actual language and then The only thing you were missing was like how to run them because of course, if you would do it in Lua or JavaScript, they were always engines for that. But what if I want to write in any language because maybe my developer team just knows like GoLang or Python or Ruby. And so they can then just, they have the power of the real language. I mean, I'm not sure it's fair to call it real language, but like they have the power to call it like an actual programming language. β And, and, and, and, and, and they, don't need to work around this. Like kind of like how we got into the. Alex Crichton
1:36:06 | π
Right, right. Glen (Plabayo BV)
1:36:12 | π
DevOps world where all these like I don't know what your opinion about is but it's super ugly like all these YAML files and and this and that and it starts to just really look like a language but it's clearly not Alex Crichton
1:36:25 | π
Yeah, yeah, it's true. I'm not going to go so far and say that every YAML file in the world should be replaced with the Wasm module, but there are certainly a lot of use cases for kind of just general configuration, which can definitely most likely better fit by having some sort of arbitrary programmable workflow. Now, not to say that writing a plugin system is easy, like you still have to design the host APIs, you have to implement the runtime, you have to do all all the kind of like infrastructure around it, but in terms of... like long-term payoff, think going that route has typically ended very well for a lot of other folks. Glen (Plabayo BV)
1:36:58 | π
Yeah, yeah, and of course, I mean, you also kind of like, yeah, reduce the barrier, right? Because if I would, let's say, I say, okay, you can write a plugin, but it has to be in Lua. Yeah, then now you have to learn Lua. But if you don't need to learn new language, I mean, that's so much easier. Okay, very cool. And so how do you see the future of like, β Wasm time, basically? Alex Crichton
1:37:12 | π
Mm-hmm. Exactly. Yeah. Yeah, definitely. So WasmTime is very, very focused right now on sort of the WSEP3 development, or I guess like I per se am focused on that. So staying up to date with WSEP3, the component model and continuing to further that. I expect that the WasmTime development to be very closely matched the component model's development for the very foreseeable future in terms of it is sort of the leading, if not the Wasm or the component model implementation. And then I think we'll continue to see a lot of work in WasmTime and sort of the β more embedded production style use cases. like a colleague of mine is working to make WasmTime more graceful in the face of OOM. So a lot of Rust programs by default will simply abort when you hit OOM. And so this is trying to transition WasmTime and kind of it returns an error on OOM and things like that. Excuse me. So I think all of those developments will continue. And then we'll inevitably continue to have more optimizations, more opportunities for optimizations in Wasm time, both on the runtime side of things, the CrayonLift side of things, more opportunities for verification and sandboxing and all that fun stuff. Glen (Plabayo BV)
1:38:35 | π
Okay, very cool. Would it ever be, I mean, I don't really know the use case of it, but I really wanna ask it, would you ever be able to run Wasm time within Wasm? Alex Crichton
1:38:46 | π
So this is, the answer is sort of. So we do have the ability to compile WasmTime to arbitrary platforms right now. We have an interpreter tier in WasmTime, which built on something that we call pulley. And so this is, you could compile WasmTime to Wasm. One of the major missing features, however, is stack switching. So we don't have a limitation for that. So you couldn't, run async Wasm inside of WasmTime. That's going to require more. more core Wasm language features or core Wasm to do that. However, one thing we have done is you can actually you can compile Wasm time with either one or both of the compiler and the runtime. So Wasm time can be thought of in two halves of like one half is like compiling Wasm modules to native code and the other half is actually running those Wasm modules on native. So you can compile just the compiler to Wasm. So for example, we can run CrayonLift and WebAssembly. So you can compile WasmTime to Wasm. You could run that in WasmTime to generate x86 byte code, and you can run that in WasmTime to actually run that natively and everything. So we have not quite the full Ouroboros just yet, but we have pieces of the Ouroboros in a sense. Glen (Plabayo BV)
1:40:02 | π
Okay, very cool. And so we kind of like working backwards, kind of like Star Wars, where we kind of like start with the future. But now I want to kind of get like to the beginnings, but also just about what it is. So, I mean, we already talked about Wasm time is like a runtime, but... Alex Crichton
1:40:09 | π
Ha ha ha! Glen (Plabayo BV)
1:40:24 | π
Like, can you maybe give an overview, like what's exactly in Wasmtime? And is it just the Wasmtime creator or is there more to it? Alex Crichton
1:40:32 | π
Yeah, definitely. The main entry point is definitely the Wasmtime Crete, and that has a whole slew of cargo features that you can enable and disable. There's things like the Cremlift compiler, the Winch compiler, which is our baseline compiler, the runtime itself, all sorts of things there. So Wasmtime comes with the ability to run Core WebAssembly. You can run components. You can define host APIs. You can call things with async. It's all the async business in terms of stack switching and fibers and yada yada. It has the GC implementation, basically everything you would expect from sort of exactly what is necessary to run any core Wasm module or component. Wasmtime does not have an implementation of Wasi, however, in the Wasmtime Crate. So it does not provide any host functionality. sort of, you have to bring everything. You have to still provide all your host APIs in that regard. So for Wasi, Wasmtime has a Wasmtime-Wasi Crate. where that obviously depends on WasmTime and uses all the same types and everything. so, for example, in WasmTime, there's this structure called a linker, where you add a bunch of functions to the linker, which are your host functions, and then use a linker to instantiate a module or a component. And so the WasmTime Wazikrate provides the ability to add functions to a linker, which you then go and use and add your own functions to, and then you instantiate modules with and everything. So that's sort of from the user-facing perspective, the two major... β crates that you'll be using in Wasmtime. And then there's a whole bunch of other stuff in terms of like, we have a CLI, the Wasmtime CLI crate, and that has commands for like pre-compiling a WebAssembly component, disassembling the pre-compiled thing, exploring that. We have various profiling commands, various debugging commands, sort of the whole gamut in between. And then there's various other crates for WASI proposals that we have a WASI NN, WASI TLS, WASI, oh, what's the name of it? WASI config, WASI key value. kind of a slew of crates in that regard. And then I should probably also mention that WasmTime also has a C API. So you have the ability to build a libwasmtime.so or .a, and then we use that to build out WasmTime embeddings in other languages. And so the primary implementation language of WasmTime is Rust. And so the primary consumption is via crates. but you can also, there's Wasmtime RB, which is in Ruby. There's Wasmtime Pi for Python bindings, there's Wasmtime Go for Go bindings, and I think Wasmtime.net for C sharp and such bindings. Glen (Plabayo BV)
1:43:01 | π
Okay and do you use β I forgot like do you use piol 3 for the the python generation or is it like manual or something else? Alex Crichton
1:43:11 | π
Yeah, not currently. This is one where I honestly didn't know Py on the 3 when I WasmtimePy. But the other thing was, at least for myself, I wanted to use the exact distribution artifacts of Wasmtime itself, so like the exact .so. So more or less, no. WasmtimePy is built on the C API of Wasmtime exclusively. So it uses C types under the hood to actually link to the library and to have a bunch of Python definitions and things like that. And Go is similar, where Wasmtime Go is built exclusively on the C API. Now, I believe that Wasmtime RB is built on, I don't know the exact name, but there is an extension for Ruby which makes running a Rust code in Ruby much nicer, kind of like PyO3. And I believe Wasmtime RB is built on that. Wasmtime RB is not built on the C API exclusively. Glen (Plabayo BV)
1:44:02 | π
Okay and so let's say okay I learned about WebAssembly, I the basics, I went through the like the WASI book or whatever you call it, I kind understand all that now. Yeah how would I need to approach like WASM time, like what's there for me, is there β like a recommended path for someone like to learn there or is it like just start using it around the fly is kind of like the answer. Alex Crichton
1:44:34 | π
No, no, no, it's, we have, definitely a good question. And we have, so we do have a documentation website of, I think it's docs.wasmtime.dev or if you Google Wasmtime, find the GitHub repo, it's linked somewhere, it's linked prominently from there somewhere. So that's sort of our main documentation book. It's got lots of examples, contributing documentation, general architecture documentation, like our release process, security process, internal design, all that fun stuff. β So that has a lot of high level examples as well. So kind of running async code, running P1, running P2, running P3, C++, C, yada yada. And then there's some examples in the Wasmtyne repo as well, just in the examples folder, various things you can explore there. then additionally, the API documentation specifically from the Rust side of things is intended to be quite comprehensive in terms of what's documented, the length to which we document things, and various examples and documentation. Some functions are still lacking. I every project could always use better documentation, but those are sort of the main resources to get started with with WSM Time. Glen (Plabayo BV)
1:45:40 | π
Because I saw that book, like books.wasmtime.dev and I kind of like went through it But I found it like a bit confusing. mean, the first part is pretty clear and I learned how to install it. can see like, okay, there's also CLI. I don't need it, but okay, I read through it anyway because I like reading. And then it went through the API, but that didn't really feel like documentation to me with more like examples and not even sure what to do with those examples because like it is these different things, different pages, but they basically always just Alex Crichton
1:45:52 | π
Yeah. Glen (Plabayo BV)
1:46:17 | π
show me the wasm source and then like host source and and like as someone that doesn't know anything about wasm time like yeah I have a hard time figuring out okay what am I supposed to do with that Alex Crichton
1:46:32 | π
That's fair. And I think we could definitely improve the Wasmtime docs quite a lot. It's one where, I know, I realized that I suspect every software project is in perpetuity able to improve its documentation, but I think that is especially true for Wasmtime for sure. So I would probably say Wasmtime is probably not the best to get introduced to unless you kind of already have in your mind a use case you want to use it for, kind of like an intended, I want to like use it in a plugin case here or... in better case here or whatever. And that I find helps shape sort of the APIs you're looking for, the examples you're looking for going sort of in that regard. But otherwise, I mean, as a standard obligatory as an open source project, we are more than welcome to receive both issues or PRs in terms of β anything we're missing in our documentation, anything that could be improved. Because I will be the first to say we can definitely improve quite a lot. Glen (Plabayo BV)
1:47:12 | π
Okay. Yeah, I mean, it's definitely not a criticism. It's more like I was trying to understand the especially because you also mentioned that's like I recommend but but I guess that assumes that you also already kind of like understand most of how it works. But like what I was kind of like trying to to get it over what I was missing is like like like let's say how would I know how to use like the library and and and or the great and what to pay attention to or is that just a matter of Alex Crichton
1:47:30 | π
you're fine, you're fine. Glen (Plabayo BV)
1:47:57 | π
use docs.rs and just go through the... I mean I guess the thing you would start with is the engine and then I guess you can figure out from docs.rs like how to configure it and how to like β compile a module or what the link is about and all these things. Alex Crichton
1:48:17 | π
Yeah, that's the general hope. mean, we've hoped that the examples are sort of like you copy paste those and then like you can kind of tweak it from there by looking up the reference documentation for like, what can I do with a store? What can I do with an instance or a linker and things like that? the jumping in with no context to the docs that are as documentation is probably going to be a little overwhelming, but it's intended to still be that. Like it tries to lay out the sort of high level things like config and engine store. a module, a linker, a component, and yada yada, all that stuff too. So docs.rs is a little bit more fully fleshed out than the docs.wasntime.dev, but they also serve slightly different purposes too. It's one, honestly, this is never something we've done very well. There's so many different questions you could ask coming to Wasntime documentation. You could be a prospective embedder. You could be an existing embedder who wants more information. You could be a guest toolchain author. You can be a guest author. All of these we've tried to cater the documentation to in the past and have not done a great job because it's just sort of a bit of a schmores board. As you've said, it has stuff, but it doesn't quite flow together super well. Glen (Plabayo BV)
1:49:32 | π
Yeah, with the Doxolaris I did quite like. I I went through it, I played with it a bit and it was sufficient for me to know that's definitely what I want to use. It looks pretty polished and so what I understood from that is... Alex Crichton
1:49:45 | π
Thanks. Glen (Plabayo BV)
1:49:50 | π
It probably is the case that I, if I have like, let's say I have like β an application which acts as the host and it's like using Tokio or multi-threaded, I would probably just want one engine which is then used like globally in my static state. And that would like, yeah, okay, that's cool. Cause first I was thinking, do I need like an engine per like thread or per connection? But no, I would probably, that doesn't make any sense at all. Okay. Alex Crichton
1:50:05 | π
Exactly. This is one where the design sort of matches the WebAssembly embedder API in the actual specifications, but it's very heavily tailored for the existing embeddings there was in time. But yes, the engine is sort of a global piece of state that all modules are compiled within. And then more or less you kind of have a store per request, which sort of serves as a thread per request in a sense. And then every store is your unit of isolation and how things are deallocated and allocated within that. Glen (Plabayo BV)
1:50:48 | π
I mean, I still find it exciting as ever, so that's very cool. Now, we cover a lot already and I took a lot of your time already. Is there like some topic that you think we didn't discuss yet, but that is really important for our like intention of like giving some kind of overview and giving inspiration to the user and to the listener like what this wasm and what they maybe want to like dive into next. Alex Crichton
1:50:53 | π
Nice. So I probably don't have, β I could speak for another two hours on this topic, but so I said that Wasm is a security sandbox or is intended to be a secure sandbox. However, β you and no one else should trust the runtime you're actually running on. Cause it turns out that every piece of software in the world has bugs. Rust is a safe language, but there are soundless holes because there are no bugs in the compiler. And so, β One thing that, mean, I'm not gonna say don't trust Wasmtime, but I can say that from the perspective of sort of a, I guess a red team-ish thing, you should not, like you should approach Wasmtime from the perspective of the question you should be asking yourself is what is Wasmtime doing to help make it secure? What is Wasmtime doing to help make it correct? And so I would love to talk a lot more about like, fuzzing that Wasmtime does, the sort of development philosophy that we have, the testing philosophy, how we use Miri, how we use CI, how we use, β how we even like make sure we test things, and like all of these sort of infrastructure around developing Wasmtime, at least in my opinion, is just as important, or if not more important than the actual runtime itself. whenever we, like all the design decisions we make in terms of like, β for example, The way that we implemented in Wasm time, the Wasm GC proposals is quite different than I think how some of the web browsers did it. I mean, we didn't have a JavaScript garbage collector just lying around that we could use because that's what web browsers are doing. But we took a very different angle from the perspective of what is sort of the, how can we best protect Wasm time from bugs in the implementation? And so it's a really fun mindset to be in of, okay, yeah, Wasm is secure, and provably secure, and formally secure. But Wasmtime is going to have bugs and Wasmtime is not 100 % correct. so going through all that and kind of gaming all that has been a lot of fun for me. especially fuzzing in Wasmtime is a massive topic about what to fuzz, how to fuzz, when to fuzz, all that fun stuff. I would highly recommend folks take a look into, we have various documentation and stuff online for Wasmtime as well, security and sandboxing and various features there in that regard. Glen (Plabayo BV)
1:53:33 | π
I yeah I write about it because it even states in your feature list that you undergo 24-7 fuzzing donated by Google's OSS fuzz. Yeah. And do you also do like a formal verification in those kind of things? Alex Crichton
1:53:44 | π
Exactly. We do to a certain degree, and this is primarily focused on CraynLift and lowering rules there. So we have folks working at various universities that are working with us to kind of formally verify, for example, that CraynLift IR semantics are preserved when we actually lower to machine instructions. And so we have some, couple of historical bugs in WasmTime where we had buggy lowerings or buggy translations. And these formal verifications have after the fact been able to catch those sorts of issues. And so it's sort of an ongoing effort and kind of whether or not those land inside of Wasmtime, how to upstream those and kind of all that integration story there. Glen (Plabayo BV)
1:54:30 | π
Okay, very cool. Yeah, I mean, that's definitely would be like an entire, I guess, different or like a separate episode just about the fuzzing and testing. like, let's say if I would suggest definitely that you hand over to me some links and resources around that. Alex Crichton
1:54:40 | π
Yeah. Of course. Glen (Plabayo BV)
1:54:52 | π
where you say like, if you want to learn about this, maybe check out like these files or these articles or these talks. β And then that's definitely very interesting for people to check about. Alex Crichton
1:55:08 | π
Definitely. We have plenty of those. A lot of us maintainers, we like to talk at conferences about WISEM time security clusters. There's a couple of different talks about WISEM times fuzzing security, rust usage, all that fun stuff. Glen (Plabayo BV)
1:55:11 | π
Ha ha ha. Yeah, very cool. Okay. So with that said, I think it's about time we round off. Like I went a bit over time, but that doesn't mind, I guess, yeah. Alex Crichton
1:55:30 | π
It's all good. I had fun. Glen (Plabayo BV)
1:55:35 | π
Yeah, me too. I I learn a lot. For me, it's also a lot clearer. Like some things which I thought like, okay, this is going to be complex and will actually turn out to be much easier. And now it all starts to tie in all a bit better together. yeah, my excitement grew by like a thousand percent. I bought like Wasm. Alex Crichton
1:55:45 | π
Nice. Very nice. I'm super happy I was able to help out there. Glen (Plabayo BV)
1:56:01 | π
yeah so thank you very much for for your time and joining the podcast and I wish you all the best Alex Crichton
1:56:08 | π
Of course, thank you so much again for having me. Elizabeth (Plabayo)
1:56:13 | π
Netstack.fm is brought to you by Plabayo building secure, open, and resilient infrastructure with Rust protocols, and purpose. This show is also made possible by Rama, the open source networking framework. Plabayo offers service contracts and welcome sponsorships to keep building and supporting its ecosystem. The theme music of this podcast was composed by DJ Mailbox. If you enjoyed this episode, don't forget to subscribe on your favorite podcast platform and leave a five-star review. It really helps others discover the show. Thanks for tuning in. We'll see you next time for the next handshake.