Pod Insights Software Engineering Daily WebAssembly 3.0 with Andreas Rossberg About this episode WebAssembly, or WASM, has grown from a low-level compilation target for C and C++ into one of the most influential technologies in modern computing. It now powers browser applications, edge compute platforms, embedded systems, and a growing ecosystem of languages targeting a portable and secure execution model.
Andreas Rossberg is a programming languages researcher and former member of the V8 team at Google https://www.google.com/. Andreas helped architect WebAssembly from its earliest concepts through its most recent milestone releases, including the groundbreaking 3.0 spec that introduces garbage collection, richer reference types, and major steps toward multi-language interoperability.
In this episode, Andreas joins Kevin Ball to explore the history of WebAssembly, the constraints that shaped its earliest design, the major turning points in versions 1.0, 2.0, and 3.0, and what’s coming next for WebAssembly.
Kevin Ball https://www.kball.llc/ or KBall, is the vice president of engineering at Mento and an independent coach for engineers and engineering leaders. He co-founded and served as CTO for two companies, founded the San Diego JavaScript meetup, and organizes the AI inaction discussion group through Latent Space.
Please click here to see the transcript of this episode. http://softwareengineeringdaily.com/wp-content/uploads/2026/01/SED1890-WASM.txt
Sponsorship inquiries: [email protected] https://cms.megaphone.fm/organizations/619b680e-d813-11ea-9750-e7ecac406436/podcasts/e60108fe-e328-11ea-b2b6-1348249f900a/episodes/3913370a-bc44-11ed-ace6-8b1f96d82bba/[email protected]
The post WebAssembly 3.0 with Andreas Rossberg https://softwareengineeringdaily.com/podcasts/webassembly-3-0-with-andreas-rossberg/ appeared first on Software Engineering Daily https://softwareengineeringdaily.com.
Transcript 10,428 words · 3 speakers
0:00 Speaker 00 WebAssembly has grown from a low-level compilation target for C and C++ into one of the most influential technologies in modern computing. It now powers browser applications, edge compute platforms, embedded systems, and a growing ecosystem of languages targeting a portable and secure execution model. Andreas Rossberg is a programming languages researcher and former member of the V8 team at Google. Andreas helped architect WebAssembly from its earliest concepts through its most recent milestone releases, including the groundbreaking 3.0 spec that introduces garbage collection, richer reference types, and major steps towards multi-language interoperability. In this episode,
0:44 Speaker 00 Andreas joins Kevin Ball to explore the history of WebAssembly, the constraints that shaped its earliest design, the major turning points in versions 1, 2, and 3, and what's coming next for WebAssembly. Kevin Ball, or K-Ball, is the Vice President of Engineering at Mentoo and an independent coach for engineers and engineering leaders. He co-founded and served as CTO for two companies, founded the San Diego JavaScript Meetup, and organizes the AI in Action Discussion Group through Leighton Space. Check out the show notes to follow K-Ball on Twitter or LinkedIn, or visit his website, kball.llc.
1:32 Speaker 01 Andreas, welcome to the show.
1:34 Speaker 02 Oh, thank you. Thanks for having me.
1:37 Speaker 01 Yeah, I'm excited to have this conversation. Let's start a little bit with you. Can you give us a bit of your background and how you got involved with WebAssembly and kind of what took you to where we are today, having this conversation?
1:49 Speaker 02 Yeah, it's been a bit of a journey. So I'm a person who's kind of on both sides of the aisle in terms of academic and industrial work. So I used to be more like a researcher in programming language, both hardcore theory stuff, but also implementation stuff. At some point, I switched over to industry, working for Google. Working on the V8 team and that's one side where the whole WebAssembly thing started. So that's how I got involved in that.
2:17 Speaker 01 Let's dive in there. Actually, I didn't realize you'd done a lot of academic work on theory. So I'm kind of curious, maybe as we go along, to explore how that has influenced development of WebAssembly. But let's maybe take us on a quick journey of the history of WebAssembly. I think, you know, if we have web programmers here, they're probably familiar, but not everybody is. So let's, let's kind of go through what was the inspiration and, and the different stages we've been at coming to today.
2:40 Speaker 02 Okay, yeah. So a bit of history was that before WebAssembly on the web, we basically only had JavaScript, right? And it was always clear and common complaint by many people that this is like not good enough. And JavaScript has problems, as we all know. And if you want to use other languages, you have to compile to JavaScript. And that's far less than ideal as a compilation target. It's also can be slow or at least very unpredictable in terms of performance. So before WebAssembly, there were already like two kind of technologies that tried to bring more, more like native code to the web. And one was a native client that was a Google technology that allowed you to do initially at least x86 code,
3:23 Speaker 02 to run that in the browser in some form of sandbox. And then a bit later, the other thing that occurred was ASMJS, which grew out of MScript, which is this tool that was able to translate C to a very stylized subset of JavaScript that engines could compile more efficiently. But that was really like a very clever ingenious hack. So it was clear that this would not scale very well, right? Like so, and at some point then it was mainly people working on the JavaScript engines at Google and at Mozilla. So Luke Wagner and Ben Titzer in particular, who got together and started the idea of like, let's do it the right way.
4:06 Speaker 02 And that's kind of how it evolved then. That was back in 2015, I think.
4:11 Speaker 01 What would you say are the constraints?
4:16 Speaker 01 Unique to trying to do this inside of a browser environment, the way that it was. You mentioned like, okay, for to get fast, we had to trim down the subset and Google tried this native x86 approach. What makes compiling to a browser environment different than just running something on my laptop or server?
4:34 Speaker 02 So the biggest constraint, of course, is that it has to be safe and secure, right? You're running untrusted code essentially on your own machine. So you can't afford like any undefined behavior or any kind of other non-safe behavior. So that is like the the topmost constraint that hovers above everything else. And then, of course, you also have constraints like the web is a very particular environment. You don't have access to most of the services that you're used to from regular operating systems, right? Like, there's no file system or anything like that. You can emulate some of that stuff, but it's not really physically there. And various other OS kind of services, right?
5:18 Speaker 02 And various programming language implementations kind of assume the presence of some of these services. So when you compile at least to the web, then some of these things have to be implemented differently. And you have to be aware of these environmental constraints.
5:37 Speaker 01 That definitely is a somewhat different environment to have to target. Let's then maybe look at what the sort of big steps have been leading up to this 3.0 release. So the first version of WebAssembly, what was in the box?
5:50 Speaker 02 So the first version is essentially was targeting customers we already had with ASMJS in particular, right? So there were already applications that just compiled a pre-existing C C++ code bases over to the web using ASMJS. And we wanted to be able to switch them over as soon as possible so that we can retire that technology and have something more forward-facing. So the 1.0 release was totally targeted at low-level languages like C C++ and Rust.
6:26 Speaker 02 And the feature set was really only you have this linear byte array as your memory model and you have the the four basic numeric data types and that was all there was to it, right? So not much more than that. You could define functions, could compute terms of arithmetic and you had your memory. And you had a way of emulating function pointers. So that was it, like very basic virtual CPU if you want.
6:52 Speaker 01 Yeah, well, and I remember hearing after that came out, there was some out, oh, this is super limited. And then people were like, hey, look, I rewrote this intensive CPU intensive library that we used to do in JavaScript. We I rewrote it in Rust or I rewrote it in C. And now it's thirty X faster. So these like stories of improvements. Uh, now those may be isolated cases. And actually, that's that might be worth coming into. You know, if you have a JavaScript application, what types of benefits do you see compiling down to WebAssembly over JavaScript?
7:24 Speaker 02 Yeah, I mean, that depends a lot on like what your domain is and what kind of computation you're doing and how dynamic it is. So if you're really just doing low level numeric stuff and you can basically ahead of time compile all that to a very efficient code, then that's where WebAssembly really shines, right? So you basically get n- next to native code performance. If you have more complicated like language runtime things, especially in one O, like you need a garbage collector or anything like that, right? Then you will have a much less pleasant time at that point because you have to emulate all that.
8:03 Speaker 02 And you you are fighting against some of the abstractions that WebAssembly imposes, mostly for portability and security reasons. So, right, that's why for more high level languages, for example, WebAssembly one O is not a particularly attractive compilation target. Also, in terms of performance, it, yeah, again, it depends a lot of what you can do, of what you're doing. So there are certainly things where JavaScript might even beat WebAssembly, the reason being that it's a way more dynamic system, right? It does because it has to. To be anything close to fast, it does dynamic profiling, dynamic recompilation and really, really crazy things behind your back at runtime.
8:46 Speaker 02 Which of course all have a certain cost to them as well, right? You're just not seeing that usually. But of course, you can easily construct cases where this is creating much better runtime than than WebAssembly ever could because it doesn't try to be as smart, right? So this has been a traditionally also fun thing with benchmarks because if you like, if you're not careful with benchmarks, then JavaScript engines could easily optimize away. Like half of your code that what you're trying to measure. And so, yeah.
9:18 Speaker 01 Yeah, I came up in the high-performance computing world, you know, twenty twenty-five years ago and benchmarks were and every compiler was trying to figure out, okay, how can I game this benchmark? But in a way that's not obvious that it's gamed.
9:31 Speaker 02 Yeah, that was like the time I was on on the VA team, like in the tens, mid tens, early mid tens, that the benchmark war was like all on, right? I think it was completely ridiculous and I still have, I feel a bit traumatized from that time and basically trust no benchmarks at all.
9:50 Speaker 01 Well, and we're revisiting that now in the L L M era and everybody's trying to figure out benchmarks and they're not necessarily representative. Let's keep moving forward. So you mentioned, all right, one O, targeting very low-level languages, languages that probably aren't having to do with garbage collecting, aren't having to deal with these other things. Moving forward then, two O was how many years later?
10:12 Speaker 02 Ah, depending on what you what you count, right? So there are the proposals and when they are done. And then there's this official process about like releasing a spec. Which in this case took years after everybody already shipped all the features in it. So technically, I think it was released in twenty-two. Practically, it was more or less done in twenty nineteen or something, maybe twenty twenty. I don't remember exactly. So that's when all the browsers implemented it and the features were completely done essentially. And the main big feature in two O was the support for vector instructions. And that was again, like.
10:53 Speaker 02 Take more advantage of like hardware capabilities, really compute intense stuff and allow them, allow applications to take benefit of what modern hardware provides in that regard. Yeah, so that was a big feature and then another somewhat, there were very smaller features. And one other interesting feature that was kind of showing a new direction was the addition of what we call reference types. So in addition to just these four numeric bit pattern types, you now have an opaque type of references. And that was two reasons at that point, one was to have more first class handling of function pointers,
11:34 Speaker 02 which we can't treat as transparent reference or transparent pointers, right? Because that would be completely unsafe. So to have a way to pass them around, you have to have a type that keeps them, that ensures that you can't peek at their bit patterns or anything. And the other reference type with external references and that was gave you a way to basically pass through host values. So on the web, that would be JavaScript values through WebAssembly code, right? You can't do anything with them, but you can hold them and round trip them. And that offered a much more convenient interop story with with the web in particular, where previously you kind of had to maintain bijections on the boundary.
12:16 Speaker 02 That was like really ugly and brittle to do.
12:20 Speaker 01 Yeah, I do remember that being a big thing of, you know, if you were going to port something over to a WebAssembly for a library or whatever, like really having to be careful about what's the interface and keeping it as slim as possible, because it was hard to to move anything around.
12:35 Speaker 02 Right, right. So, yeah, so external references, at least in principle, made that easier. But also, these were kind of like the inroads to what followed later with garbage collections of a much richer system of reference types.
12:50 Speaker 01 Yeah, well, and it feels like in a lot of ways, three O, which is what what brings us together here, was just a mammoth step forward in capabilities. I was reading somewhere that some of these things had been sort of in development for seven, eight years, which is just a mind blowing timeframe for anyone in the tech industry, how much this changed in the last seven or eight years. So let's talk about the big release, three O, what was in the box and what did it look like?
13:16 Speaker 02 So the biggest feature arguably is the addition of, yeah, garbage collection, right? So that's what I just mentioned with taking reference types to the next level. So you now have support for defining your own reference types and a memory layout for them. And then the WebAssembly engine takes care of allocating and reallocating them. It's noteworthy, though, that we try to make sure, so this is has been a somewhat controversial feature because it's like, okay, that is no longer just like abstracting a CPU feature, right? It's it's a bit more high level. But we were very careful to kind of stay within the spirit of WebAssembly of being a low-level language.
14:01 Speaker 02 And I always phrase it as as low level as possible, but no lower. And so this is a very low-level GC feature in the sense that all you get is essentially structures and arrays. You don't get any objects or anything like that built in like you would have in other VMs like the Java VM or something, right? So it's really low level. All you, what the types are doing, they describe to the engine what memory layout you want. But you still have to map all your runtime data structure from your language to that low-level representation, like you would do a native code, right? The only difference being that you tell the engine to allocate this stuff for you or one particular deallocate it.
14:45 Speaker 02 But the complexity there is that, yeah, these type descriptions, if you want to avoid a lot of runtime checks, then you need a more clever type system that always knows what what it is you're referencing without having to do any CAS or at least a minimum amount of CAS. And that's where the type system then becomes significantly more complicated. So, yeah, that was one big thing. Uh, let me quickly look at the list, uh, so I.
15:13 Speaker 01 Actually, before we before we go further on that, so since you're targeting not only languages with garbage collection, but still those original languages, is that opt-in? How do you, how does one?
15:23 Speaker 02 Right.
15:24 Speaker 01 Interact with it?
15:25 Speaker 02 So it's basically completely separate from the this linear byte array that you had before. You can still use that. You can use both together. You can completely ignore the instruction set, the part of the instruction set that deals with GC. And then everything will be as before, right? Like you just don't have to use it. And some people have been worried about this creating extra cost in the engine and actually no, because like in web engines in particular, all it's doing, it's giving you essentially access to the garbage collector that was already there for JavaScript, right? So now you can allocate something in there from WebAssembly code. And that's all that changes. They have one combined GC.
16:10 Speaker 02 So and that obviously was there before, so nothing, no extra cost there if you completely ignore this stuff. So yeah, it's a completely separate memory area that does not overlap at all with with the linear memories.
16:26 Speaker 01 Yeah, no, that I think that's key. It reminds me of like Rust has this principle of cost-free abstractions, right? Like anytime they can implement something that that doesn't have a runtime cost. Great. In this case, maybe it has a little bit of a runtime cost, but it's opt-in. If you don't use it, it doesn't layer any cost to the other pieces.
16:42 Speaker 02 Exactly. And and yeah, we also have that philosophy. I think C always had that philosophy or C++ they always call it pay-as-you-go or some or maybe that was somewhere else. But yeah, there are various names for that. And that's definitely a philosophy WebAssembly is also following.
16:59 Speaker 01 Yeah, I was looking at at the feature list just before this, so I can bring some of them. Another one that I saw that I'd love a little bit of a dive into what it means is this concept of having multiple memories.
17:09 Speaker 02 Right. So this is more actually a technicality because contrary to popular belief, you already were able to have multiple memories before. You just were not able to access multiple memories within a single module. But in WebAssembly before, you could have multiple modules that talk to each other and each of them defines their own memory. That was totally okay. There was just this weird gap that you could not bring them together in a way that you can directly talk and move values between multiple memories. And that was both kind of like a performance. Cliff for for some kind of things that want to do that. And it was also a gap in in the design like in in terms of modularity.
17:54 Speaker 02 So there are these these tools that are basically acting like a static linker. So they take a set of modules and merge them together in one bigger module. And that worked with everything except memories because you could not have multiple memories in one module. Right. So in general, this would fail if more than one module defined one. And now that was one of the kind of intentional gaps we left in the initial design of WebAssembly 1.0 and always were meant to fill later. And it was more like, OK, we need to get something out of the door quick. So let's defer that. And now now we've added that. That was basically one of the last kind of intentional gaps that we left initially that we filled in now.
18:36 Speaker 01 It might actually be worth, just from a design's perspective, because I think building a whole, I guess in this way case, compilation target, a whole assembly level language that is pretty low level. Like, that's a that's a programming domain not many people have explored. Like, what types of intentional gaps did you leave in that 1.0? And what was like, how did you think about that? What were the trade offs evaluated?
19:01 Speaker 02 There were like three main gaps in terms of, oh, OK, here we only allow one of these. When really, in in general, in the future, we want to allow multiple of these. So the first thing was multiple values, right? So function or instruction initially could only return one result. And that was kind of silly in terms of a stack machine and constraining. So we lifted that. And that was already like in the original paper we published that already had that worked out. And then the other two were multiple tables and multiple memories. So multiple tables kind of sneaked in in 2.0 as part of the reference types extension, because that meant that previously you only had function references.
19:45 Speaker 02 So you could just do everything with one table. But now you have multiple reference types and we use tables in a more general way. So you need tables of different type, right, that naturally require. RSU to be able to define multiple ones. And then the the multiple memories was the was the remaining one we had it later. There has been talk about having multiple start functions, but that is not that you can easily work around that. But yeah, so these were kind of like gaps we left in there where the all instruction set and binary format already kind of anticipated that we will add them. Other than that, it was more like, okay, let's for now stick to the feature set of things that are already in ASMJS.
20:30 Speaker 02 So we have to cover everything in there. And then also, what is the in the intersection of all common CPUs at that point? So that everything that has a one to one translation in terms of instruction mapping to actual hardware, that is an easy one. And I think we didn't leave that many gaps there. There are more gaps now with Simdi, for example, because Simdi is a much more much sadder story in terms of hardware support. Where hardware vendors really can't get their shit together and agree on what the instructions are and what their corner cases are. And what the feature matrices matrices are, and there are like random gaps in there that I really personally hate.
21:12 Speaker 02 But we're just one hardware would not allow an efficient mapping of this particular case. So we leave it out and maybe at some point we had that. Basically, we we always have this MVP concept, right? In a more general fashion, which is, okay, let's always start with something that makes sense. And we already know we want to extend it later, but have something that works and that we can ship. And people start using it and we get feedback and experience and have a clearer picture of where we should take it from there. So WebAssembly one O as a whole was an MVP with garbage collection. Like what we added now is sort of the garbage collection MVP. There is a whole list of post MVP features that we have in mind that we might want to add at some point.
21:57 Speaker 02 But they're that are not and totally essential, right? You can get by without them. So this is more like the usual kind of thing we're doing. We're we kind of try to keep the broader picture in our head, at least with have a rough idea how how that could be integrated later. But focus on the things that we can solve quickly enough, even though it still might take eight years, I don't know.
22:22 Speaker 01 Yeah, I'm curious, actually. So one, as you're getting that feedback from each version of MVP, which I think is, that is the sort of approach that we all at least idealize as an approach. It's not always easy to follow. Is that feedback from browser implementations? Is that feedback from compiler implementers? Like, what were the different things that ended up shaping from 1.0 to 2.0 to 3.0?
22:48 Speaker 02 Yeah, it's often like, sure, compiler writers, engine writers, framework writers. Sometimes it's CPU vendors that want to push there. Like, this is a bit of what happened with Simni. There was a very strong push from CPU vendors to have support for their ultra cool and fast feature. So at that point, it might be somewhat political. But yeah, usually it's kind of for the bigger features. It's a broad understanding of, okay, we have this low-level language and there clearly are things we can't handle yet. But what would that mean in terms of a feature? And then we design these bigger features. So like GC was a discussion from the beginning. Exceptions is another thing that's in 3.0 now, right?
23:33 Speaker 02 Which also was in the making for very long. Threads is another one that go, although it's also already implemented everywhere and has been for years. The biggest gap now is still missing is something like some continuation-like feature. Maybe we want to talk about that later. But this always thinks like, we know that there are some like language features you can't compile currently because there's some functionality missing. Right? That is one big thing. And usually as engine people and compiler people, we know what these things are. And we, we already have plans to some degree for attacking these at some point. Modular priorities. And then sometimes there are smaller things that just come from clients, users,
24:19 Speaker 02 third-party compiler writers that notice, oh, you know, this is kind of a thing that would be good to have here because I can't do it easily the other way. And then they propose something as well. Yeah, like that. I mean, this is a process. I don't know. How aware people are is like completely out in the open. WebAssembly is totally like an open source project in a way. And the committee is is open for everybody, right? So in in theory, everybody can join there and propose a feature. But there is a very elaborate process you have to go through to push that feature over the over the edge in the end. In particular, you have to convince the the rest of the committee that it's worthwhile. But that has happened a number of times, so.
25:04 Speaker 01 Well, actually, I wanted to to kind of ask, are there any features that have made it out in one of the two or two dot O or three dot O releases that you did not anticipate? That were not sort of already in the back of your head of like, oh, yeah, we'll want to do that eventually?
25:19 Speaker 02 So I think more of those are kind of landing now. Now that we have gotten over the hump of the big features that we wanted to do from the beginning. Maybe one thing I didn't anticipate was this relaxed SIMD kind of extension that we have in three O now, which is also, to be honest, not a feature I'm particularly happy about. That's a different story. But other than that, most of these are kind of, yeah, have been in the making for a long time and always was a trajectory to them. I don't know when we started talking about sixty four bit address spaces, but I I'm pretty sure that also was from the beginning that eventually we will probably support a larger address space.
26:01 Speaker 02 So, yeah, it's a good question, but actually, in in the releases so far, there aren't that many features that were not kind of that came up much later. Maybe it just being a function of how long it takes to add a feature.
26:14 Speaker 01 Well, and and in a lot of ways, I think this is well-trodden ground in terms of
26:21 Speaker 02 Yeah.
26:22 Speaker 01 you're supporting all of these different languages. And so you're you're kind of catching up to the the cutting edge in a lot of ways. And then at some point you catch up to that frontier and then there's a
26:32 Speaker 02 Right.
26:32 Speaker 01 pushes forward. Speaking of that, I think one of the things that I saw that I thought was interesting was three O added tail calls as well, which I think is a very important functionality in terms of enabling efficient use of of more functional languages. I'm curious, kind of, if you look at the the spectrum of languages, what does support for compiling to WebAssembly look like now? Are are there any languages that are not actually supporting this yet or?
26:59 Speaker 02 Well, I mean, that's up to the languages, but I would think that most languages that have a certain user base have some form of support for WebAssembly at that point. And three O, especially with garbage collection, but also Tailcards was an enabler for a whole new set of languages targeting it now, like functional languages like you mentioned, but also other G C languages like Java and um C sharp and they're using that instruction set as well. Yeah, I I mean, there are so many languages out there that I don't have anything closer to complete knowledge of who who has a WebAssembly backend and who hasn't, but most of the languages that I come across, usually they they already have it in some
27:44 Speaker 02 form with varying maturity, of course. But yeah, it's very much a thing these days in your compiler ecosystem to at least consider it.
27:55 Speaker 01 So looking at that now and looking at how much easier it is to navigate across the JavaScript to WebAssembly border now with these new features that you have this wide language support. Can we revisit the question of when does it make sense to use a language targeting WebAssembly versus JavaScript or TypeScript? I think the the calculus has probably changed a little bit since one dot O.
28:17 Speaker 02 Yeah, absolutely. So, right, so more high level languages, especially G C languages are it is much more reasonable to compile them to WebAssembly now. I would think that actually it's reasonable for for most applications. The only thing if if like if you're really building something that all what it's doing is DOM interaction and manipulating the DOM, then you probably won't get much value out of it, right? Definitely not in terms of performance. It won't necessarily be slow either, but you might have to jump through extra hoops with all the glue code and so on and so forth, which is much quicker if you can just do it in JavaScript directly. So that is the main domain where I would say,
29:02 Speaker 02 okay, it's probably still better to use JavaScript or. Potentially, if you're compiling a language that is very closely integrating with JavaScript by design, right, then that might also be better to still target JavaScript itself.
29:17 Speaker 01 So that's kind of actually an interesting thing to discuss. So when I think about building an application in JavaScript and particularly for the web, you have JavaScript, the language, all the runtime and libraries, but you also have all of these web-specific APIs that are available in JavaScript. Are those exposed directly in WebAssembly as well if you're building for the browser? Or do you have to hop over to JavaScript to access the API and then hop back?
29:42 Speaker 02 Yeah, yeah, that's a famous kind of question and complaint. Oh, give me DOM access, right?
29:51 Speaker 02 The thing is, yeah, right now you don't have that. And that is, that is actually a very important part of the whole WebAssembly security model, that it's completely sandboxed, right? You have no ambient capabilities to have any access to your environment whatsoever. Anything you can do or interaction you have with your environment has to come through imports. And that's like core to its very tight sandboxing functionality. So what you have, though, is this very tight integration with JavaScript in the sense that a WebAssembly function you import can just be supplied as a JavaScript function, providing the kind of signatures match up sufficiently well.
30:31 Speaker 02 So basically, you can just import JavaScript functions and then just call them as if they were WebAssembly functions. The problem, of course, is that all the web APIs are really totally designed for JavaScript and they don't really make a lot of, or many of them don't make a lot of sense in terms of a more moderate kind of object system language. So you usually end up having to write some, or may have to do some glue code there. But this is more like a tooling problem. So people often make the assumption that it would be way faster if if they could access, say, the DOM from WebAssembly directly, but that's not actually necessarily the case.
31:13 Speaker 02 In particular, since JavaScript engines already go to way more lengths to optimize all sorts of things about accessing objects and JavaScript objects and DOM objects. And that would be ton and a megaton of stuff that you would have to replicate in the WebAssembly code generator, and I don't think anybody is willing to do that because it's kind of silly, right? You wouldn't even, probably not even get much performance out of that. Because the overhead of calling from WebAssembly into JavaScript is actually mostly dominated by the actual work done in the DOM itself, right? With most of these calls. So the assumption that it would be way faster or something is not actually very accurate.
31:58 Speaker 02 That being said, there is some some work now. So what one thing you would like to have is at least have some kind of interfaces for accessing the DOM, which people sort of agree upon. And that is something that is sort of a separate layer from WebAssembly Core itself, right? So people have now started looking into this in in the context of of this component model work. And so that might be something like, maybe similar to to these WESI libraries but for the web. So we start defining interfaces and they grow kind of organically. And maybe at some point, when they are mature enough, we've iterated enough on them, then we might even standardize some of that.
32:43 Speaker 02 But until then, it might just be a library or tool chain that just does this for you and you don't have to worry about it anymore. Because that's the other thing, right? The web API is is A gigantic and B a moving target. So standardizing anything around that is kind of a a challenge, right? Like you.
33:05 Speaker 01 You were more generous than I was. I was gonna say a fool's errand.
33:08 Speaker 02 Yeah, and then you have to go through the the pain of like trying to find the the ni- a nice mapping to something that makes sense in WebAssembly and possibly for more than just one language that wants to interface.
33:22 Speaker 01 That was the thing that I was going to to ask is now that you have relatively flexible, a relatively flexible type system, is there actually a substantial difference in terms of the interfaces per language? Like WebAssembly is pretty, leaves a lot of that to the the language compiler.
33:38 Speaker 02 So there's still no like sort of automatic interoperability between languages, right? And that is very intentional because that in practice never works. Like because even the smallest impedance mismatches basically usually break everything. So it was very much an axiom in WebAssembly's design that we not try to solve this problem because it's essentially insolvable, at least on that level. And trying to solve this is sort of what the component model tries to do, right? That defines this somewhat more high level, language agnostic type layer, which is more high level as well than GC types we have in WebAssembly now because I mentioned that these are very low level, right? They they don't know what an object is or anything like that.
34:21 Speaker 02 They just talk about low level representations, really. So the component model has more high level types and they are particularly designed for multiple language to be able to to map to them and talk through these with each other, right? And that would be the preferred way to also define maybe a web API for WebAssembly. So on this level of type system that everybody knows already, at least if they want to implement against the component model, they already know how to talk to. And have mapped to their language.
34:54 Speaker 01 Let's maybe step back a moment and describe the component model. So this is another WebAssembly spec, or what exactly is it?
35:02 Speaker 02 So this is ongoing work still. And at some point, it might be a different spec, but we're not quite there yet. So this is trying to define a separate layer on top of WebAssembly itself, which is like a more advanced module system, if you want. That's one view of it. Plus, a more high-level, language-agnostic type language to describe interfaces, right? And with that, you can basically specify how you bundle WebAssembly modules. You can define how they instantiate each other, probably, and things like that. And then there is this closely connected to that, this WESI effort, the WebAssembly Systems Interface, which tries to define a whole set of
35:47 Speaker 02 kind of standard, in air quotes, interfaces with respect to this component model. So that, like, that are operating system abstractions, for example, so you can use them. And there are different ways to implement these interfaces. Either a WebAssembly engine implements natively, so you have direct access to your hosting line, or they could be virtualized in other ways. And the component model is pretty rich in allowing various ways of implementing interfaces and plugging things together for virtualization and stuff like that. But yeah, so that is ongoing work still. It's a very complicated problem to solve, as you can imagine. And many people tried to solve that problem before.
36:30 Speaker 02 And there have been various technologies that don't have the best reputation historically. I'm not much involved in that, other than like talking to the people doing most of the work. But we are kind of very careful to not try to repeat the mistakes, have a more constrained system and take advantage of some of the inherent design advantages that WebAssembly has, like the strong sandboxing and all that, right? And the strict portability. So it tries not to solve all the problems in the world at once. Once it makes some informed opinionated choices like when modules of different languages talk to each other,
37:09 Speaker 02 it's all like a shared nothing concurrency model. So you can't really pass pointers across the boundary because that introduces all sorts of extra problems, right, that you want to avoid. That might also mean that it doesn't solve everybody's problem, but at least it solves a certain set of problems in that space. And from there, we can maybe get more experience about other points in the space after that.
37:35 Speaker 01 Got it. So to sort of play back to make sure that I understand, right now in the WebAssembly world, if you had different language implementations of different modules, there's no guarantee at all that they're going to be able to talk to that. That's basically on the developer to say, here's the defined interface that you have to to match and go. And so probably most people are making or developing these things as a as a pluggable piece, either all built in one language or they're owning the whole system that's interacting. And what the component model, if I'm understanding correctly, is saying, let's define a higher level interface that is true across languages so that you could build essentially libraries or modules that can interface with each other without having to know the whole system front to end.
38:18 Speaker 02 Yeah, I mean, the the situation with bare WebAssembly is kind of like with hardware, right? So you have your your hardware types and that's it. And then if you want to have different compilers be able to talk to each other or to talk to an operating system or some other kind of environment thing, you need an ABI, right? An application binary interface. And that is something you can well define on top of WebAssembly. So far, nobody has done that, although like a few weeks ago, when we had the last face to face meeting, there was actually talk about defining a C ABI for WebAssembly, which is the main one that everybody wants, right? So you at least know how to talk to a CFFI or something, and that is standardized across multiple compilers.
39:00 Speaker 02 And the component model you can view as an ABI on steroids if you want, like, because there's a kind of, it's not a fixed ABI, you have a glue layer in between. You can define how you interface to that. But yeah, other than that, that's exactly what it is.
39:16 Speaker 01 Well, and this starts to, I think, take you out of the world of WebAssembly is a way to build singular web applications and into a world where you say, okay, WebAssembly might be a generalized operating system or virtual machine that you can target for different reasons. So let's maybe actually divert over here. We've talked a lot about web use cases for WebAssembly. What are some of the non-web use cases that people are wanting to use this for?
39:44 Speaker 02 Oh, there are many web use cases at this point. Actually, the web is just one among many at this point, which kind of we hoped for from the beginning, and it worked out better than we expected. I mean, we made very sure that the WebAssembly design and also the spec is not at all tied to the web or JavaScript for that matter, right? And the web in the name was more like a marketing thing, if you want. It's really intended to be like this, maybe a bit high above a universal VM, if you want, right? So what are the use cases? So people are using it for edge computing a lot, right? Like, Fastly is the biggest company doing that.
40:28 Speaker 02 They bet everything on WebAssembly there. Lots of use cases in embedded space, which kind of confused me for a while, because why would they take this overhead when they have small CPUs anyway? Well, it turns out the big feature for them is portability. So we have people from Siemens, for example, in the working group, who explain that, you know, we have all these embedded devices and there are new processors every year or month or whatever, and it's a pain in the ass every time you have to rebuild your entire tool chain. And now, they don't want to do that anymore. They want to have a WebAssembly tool chain and then basically just switch out the backend for their CPU directly, right?
41:10 Speaker 02 But they have this very different use case from the web, because, first of all, they have much smaller systems, so they need a much leaner runtime, ideally like zero size, if you want. And they also want to do ahead of Time compilation. They don't want to do GIT compilation like you do on the web, right? They have this whole tool chain, but in the end, they compile to the actual hardware they want. And of course, WebAssembly was designed with AOT in mind as well. We always wanted that to be an option. So we also took a lot of care to not shut the door on that. And there are other kind of optimizers that take benefit of that. But yeah, actually seeing that happening for you is also interesting.
41:55 Speaker 02 There are more fancy use cases like in AI where you kind of use WebAssembly to control pruning in some search or whatever. So you make some things programmable, but in a portable way, right? With a very universal language, like you script your pruning algorithm that way. I think Microsoft did something like that. There are blockchains who use it as their execution platform. And there, one of the features they are particularly interested in, besides like the sandboxing, is the well-defined deterministic semantics. Because if that's the code you execute on a blockchain, I mean blockchain is all hype word, right?
42:37 Speaker 02 But what matters there technically is you do replicated computation and then you rely on consensus between the different replica to deliver the same result. And of course, that won't fly if you have under-defined, under-specified behavior all over the place, because then everybody will disagree all the time, right? Like, and WebAssembly is to a large extent fully specified and fully deterministic. And with three O, we even have a deterministic profile now, which is kind of specifying if you really want to be fully deterministic. This is what it means. So everybody has a clear picture of what that means and can depend on that. So you always get the same result.
43:18 Speaker 01 So let me, let me actually dig in a little bit on this because I think naively, I tend to think of most traditional programming environments as being deterministic. As contrasted to now, we do all this stuff with machine learning and L L Ms. And that's where I think of, oh, that's non-deterministic.
43:33 Speaker 02 I should explain to you that deterministic is used here in more like a. Abstract way. So we say that a language semantics is non deterministic if it is maybe specified but allows multiple different behaviors. So and then any particular execution or any particular implementation can pick one of these. But the point being if you run on different hardware or maybe under different hardware constraints, right, then you could get these different behaviors, right? And that's what you don't want. So the way you model that semantically is usually as non determinism. So just you get a random pick of the allowed.
44:13 Speaker 01 Got it, got it, got it. So this is places where essentially the language spec does not fully pin everything down. And so different implementations of that on hardware or just different compilers or whatever can make different choices. And so it may be deterministic within a single environment, but across environments, it's not deterministic.
44:29 Speaker 02 Yeah. And even within a single one, it sometimes might not be, you never really know. So there was WebAssembly 1.0 was very neat in that regard. There was only one little source of non determinism, which was with floating point arithmetic. So if they generate NANS, then unfortunately, the IEEE standard for floats failed to define what the bit patterns are for NANS and all the hardware vendors completely disagree on what they do and even how they interpret these, right? So there are funny things like IEEE defining a quiet bit or signaling bit on NANS. But it doesn't define what way it's to be interpreted, whether one is signaling or zero.
45:11 Speaker 02 And surely hardware disagrees on that choice, right? So silly things like that. And initially, we tried to even knock that down and say, okay, if your hardware's behavior diverges from what we specify, you have to normalize all your NANS. But turns out that is very expensive. You don't really want to pay the cost because then all float computations get more expensive. Although that's what, for example, blockchain implementations do exactly, right? They do that. It's not that bad, but you pay a certain price for that. Right? So that is the kind of thing why we have non determinism on the spec. Level. Of course, you also have natural non-determinism. Once you start talking about things like threats, right?
45:54 Speaker 02 Because that's essential in the concurrency model that you have non-determinism. That is more like intentional non-determinism. That's really core to what the feature is about. But all the other are sort of like accidental non-determinisms that are just really under specifications. Because we can't do better. And the less we have of that, the better.
46:15 Speaker 01 Yeah. Well, and this is sort of a level of care, or if you're on the other side, like pedanticism, that most developers never have to worry about. But if you're a language designer, all the way down. Okay, so we talked about some of those use cases. We talked about how hardware embedded folks might be doing this to simplify their tool chain. Blockchain, you talked about determinism. What are some of the other drivers for non-web use cases to adopt WebAssembly as their target?
46:42 Speaker 02 I think it's usually two things. One is portability and the other is the sandboxing model. And of course, the fact that it's pretty universal as well, right? So it's like to incomplete, you can compile everything into it. It's not constrained in any particular way. So those are the three reasons why it's a good fit for various places where you want to kind of embed some form of compute without tying yourself to whatever, like the specific scripting language or open security holes or whatever, right? So that's kind of how you make use of it, yeah. And it's also fast, which sometimes is a bonus as well.
47:20 Speaker 01 Yeah, so I think the the example that comes to mind for the closest to that sort of universal virtual machine model that anyone's come before, I think, is the JVM and all the different JVM targeting languages. What are the factors that might cause somebody to move from a JVM environment to a WebAssembly environment? Are they exactly what we just said? Is there some other nuance we're missing?
47:42 Speaker 02 Yeah, I mean, the JVM is interesting because that is really a VM that was designed for Java, right? And it has all, it's basically an abstract syntax for Java, if you want. So it has all the Java object model built in, which is pretty heavyweight, including all the reflection stuff and so on. So, and there are other things it doesn't have built in, right? You can't do, so when you compile to JVM, and many languages have done that. Usually if you don't happen to be like very much exactly like Java, then it's not going to be very fast. There are things like, so for example, with the GC extension now.
48:24 Speaker 02 One thing we have that other VMs don't have is we have tagged pointers. So I don't know if you know what tagged pointers are, but if you have a garbage collection runtime, then usually you have, the garbage collector has to know what a pointer is. And sometimes you want to unbox integers so that you don't have to put everything into a box and allocate. So you usually use pointer tagging, which is you, you take a bit off every pointer that marks it as an integer. And then you can just use an integer as if it was a pointer and the GC knows about this bit and just follows the real points. And that's something we actually provide directly as a WebAssembly feature. Whereas in other VMs, you don't have that.
49:07 Speaker 02 But there are many language runtimes that make heavy use of such a feature to like avoid boxing all their small types, right? And yeah, do things like polymorphism much more efficiently. And you pay in with, with the JVM, you, yeah, you pay the price for the heavyweight object model. So if you're compiling a language that, for example, has lots of very small allocations, which is, for example, the characteristics of many function language, then that would not be ideal for, for you because, yeah, your characteristics run against what it's optimized for. And then there are other things like, I don't know, if you want to do closures and stuff, that's also very costly in the JVM because it's not like native to it
49:50 Speaker 02 and you have to encode it in heavyweight ways and all these things, right? Like you don't have access to the low level as much as you have in WebAssembly. So you have to jump through more hoops in a way.
50:02 Speaker 01 So. Let's now look forward a little bit. What does the next generation in WebAssembly look like? What can't WebAssembly do well right now? We mentioned a little bit the component model, and that is as a big area of exploration and focus. You also sort of had a throwaway comment about continuations. Maybe we can dive into that. But yeah, what's coming down the road?
50:26 Speaker 02 Right, so in terms of bigger features, I mean, there are various small features in the making, but the two big features I would say that are still missing from core WebAssembly, so not the component model, is threads is the one which is sort of on the finish, close to the finishing line, finally, I hope. And the other is what is used to be known as stack switching, or which turns out we model it as this form of delimited continuations. And the reason this feature is important, because this is what allows you to compile at least efficiently all these control abstractions that modern languages have. And control abstractions are things like, I don't know,
51:10 Speaker 02 async await, generators, green threads, name it, right? All these things where you have non-local control flow. And usually, these are implemented, or often they are implemented in some way or the other by having multiple stacks that you switch between. And when you're in a system like WebAssembly, where you have to be type safe and where also the actual stacks are kind of encapsulated, you can't really get to them for safety, security reasons. Then it turns out that there is a neat abstraction that is already well-known in the programming language field for decades, which are continuations or delimited continuations. So that is kind of like how we model them. So you have a way of, and basically continuation is a new stack,
51:55 Speaker 02 if you want, you have a way of creating a new one, and then you can resume their computation there, which basically switches over to that stack. And then that computation can suspend, which switches you back to the point where you resumed, very roughly speaking. And you can have as many of those as you want.
52:13 Speaker 01 So I assume that since those control flow features that you mentioned are in a number of languages, including some that I believe already target WebAssembly. How are they supported today? What will this take you forward to?
52:27 Speaker 02 There are many kinds of ways to do that. So the most powerful way where you can do all that is you do a global program transformation called CPS. So Continuation Passing Style, where for every function you have an additional parameter, which tells it where to continue instead of returning. That is also a well-known technique, but you can imagine that is pretty expensive. So some languages actually do that. Others use tricks by, I don't know, trampolining through JavaScript, for example. That is, by the way, also how C++ implemented exceptions before WebAssembly 3.0, right? It had to call into JavaScript to create an exception handler, then call back into WebAssembly to actually run its body and so on and so forth,
53:12 Speaker 02 which is also kind of crazy. And of course, it only works when you have JavaScript. That's one technique, yeah. So once you have exceptions, you can do trampolining, which is you just build up your call stack and eventually you throw back to a scheduler that then somehow has an idea of how to build up the call stack again if it has to. And there are various techniques like that. They all have in common that they tend to be brittle and costly to some extent and not very modular. So one of the features our proposal has, which is something that came out of academia in the last kind of 15, 20 years. It's based on this idea of effect handlers,
53:53 Speaker 02 which is essentially, the simplest way to understand is a generalization of exception handlers that allow you to resume from, at the point where you threw. And, but you can resume at any later time. So, and the thing, the continuation is essentially your object that allows you to resume. What effect handlers give you, as opposed to these other techniques, is that you can compose these handlers in a nice way and without them interfering with each other. Whereas if you have to manually do these transformations and you have more than one of these control effects in your language, then you have to do all of them kind of together.
54:35 Speaker 02 With effect handlers, you can do them in modular ways, separate from each other. They don't have to know much about each other. You can just suspend over another handler essentially. And that is very nice. For example, if you want to do both threads, so green threads, virtual threads and say async await or generators, then one is in a much smaller scope, but you still want to be able to suspend the entire thread that runs the generator by directly going to the outer one, right? Without the generator logic having to know anything about that.
55:10 Speaker 01 No, I think it's really interesting. We've had a number of conversations with different folks about kind of advances in the programming language world. And like, we have these newer languages that are building on these capabilities that have really just happened in the last 10, 15 years. If you look forward even further, so that's what's on the horizon now. Where, what else is in the back of your head of, we're going to want to get there eventually. We're going to need to get there. What you want to enable with WebAssembly?
55:42 Speaker 02 Well, yeah, I mean, we already got quite far as far as I'm concerned. So one thing I would like to see is WebAssembly having more built-in support, like in standard operating systems, for example. So it's in every browser, but why does, I don't know, macOS or Linux or Windows not support it out of the box, right? So that you can actually run just desktop applications using WebAssembly. So it becomes even more of a portable format. And the extreme point of that would be to put it into hardware. So I keep hearing people talking about that and considering the ideas. So far, as far as I'm aware, nobody has actually tried to do that for real.
56:25 Speaker 02 And there are some hurdles you have to get over, but in principle, it should be possible. And that might also be very interesting. Because it's a virtual CPU ultimately, and at least some feature subset of it should be possible to implement more or less directly in hardware.
56:43 Speaker 01 So what you're saying is the next ARM spec or something like that is directly targeting WebAssembly?
56:50 Speaker 02 Well, not the ARM spec, but there might be a Wasm processor, a Wasm CPU of kinds, and maybe a custom ship or whatever, or FPGA or something that people who want to run that in certain environments can take advantage of. I don't know, something like that.
57:08 Speaker 01 Love it. Well, we're coming close to the end of our time here. Is there anything we haven't talked about yet that you think would be good to leave our listeners with?
57:17 Speaker 02 Yeah, I mean, one thing I could briefly mention is, because I'm heavily involved with that side, is the specification side of things with WebAssembly. So one thing we're particularly proud of is that not just don't we have undefined behavior at all, right? We have everything formally mathematically specified and verified. So we have machine verified proofs that we don't have undefined behavior. And there's a lot of work going into that and extending the kind of infrastructure for that now with various research teams that hook it up to various theorem improvers to do even more fancy things of theorem improving reasoning about programs
57:58 Speaker 02 and things like that, which I think is a whole new level for an industrial programming language that nobody has done before either. So that's something I'm particularly interested in as well, because that ties back to my academic self,
58:13 Speaker 02 half of myself that likes that stuff too. But I think it's very valuable. And I mean, the reason that WebAssembly has such a clean and fairly safe design is because we design, or one of the reasons at least, I would claim is that we design it with formalization hand in hand, right? We didn't just, you know, build this artifact and then try to make sense of it after the fact. We really did it at the same time. And that's when you kind of have to be honest with yourself when you're designing something and you have to formalize it and the formalization becomes hard and probably the design isn't quite right. So it's a nice feedback loop in the similar way that implementation is a nice feedback loop.
58:55 Speaker 02 You want to do all these things in parallel and feed back into the design. So both for semantics and performance and these things. Which I I'd love people to explore more, also for other languages. And that would give us also then the the other nice thing about that is that this gives a way of actually doing verification in depth, right? So because we now have verified hardware, we have a verified engine like WebAssembly, and maybe we can now build more verified compilers, and then you can actually verify the entire software stack at some point. I would love to see that kind of thing because frankly, the state of the art with our kind of craft is still like, these things be desired.
59:41 Speaker 01 And not to be too much on the the bubble area, but if we're using non-deterministic machines to generate code, which is what more and more people are doing with LLM-based programming, having a way to deterministically validate and verify it after the fact is going to be ever more important.
59:59 Speaker 02 Right, yeah, absolutely. Yeah, the more code we that be generated by dubious sources.
1:00:09 Speaker 01 I mean, humans are pretty dubious as well, I'll say. Like, I I've read a lot of human-written code that that feels pretty dubious to me.
1:00:17 Speaker 02 Fair enough, yeah, yeah. But for for some reason, people are less willing to trust humans when writing code than they are to willing to trust AI when it's writing code. There was just a study coming out, I just read about today, that is a bit scary. So when you're when you're pair programming with a human partner, then you usually question everything he's doing. When you do that with an AI, not so much, although it's at least as failable.
1:00:44 Speaker 01 Formal validation of the outputs.
1:00:46 Speaker 02 Yeah.
1:00:47 Speaker 01 Definitely would be nice.
1:00:48 Speaker 02 But that's very much an open research area as well, because it's a very hard program problem in general.
1:00:54 Speaker 01 Awesome. Well, thank you, and let's wrap.
1:00:58 Speaker 02 Thank you very much.
Previous America Under Surveillance with Michael Soyfer Next Next-Gen JavaScript Package Management with Ruy Adorno and Darcy Clarke Page updated November 6, 2026 · transcript and summary are machine-generated