 All right, everyone. We can go ahead and get started now, I think. Welcome to Cloud Native WebAssembly and how to use it. We've got an hour and a half here in this room, so I'm pretty excited to see what we can get done. Part of this workshop will be introducing and talking about WebAssembly, its context in Cloud Native, the projects that myself and Michael work on, WasmCloud and WasmEdge, both CNCF Sandbox projects that have applied for incubating, which is really exciting. And then there'll be some interactive portions in the middle of the workshop that will kind of run through live, and you can follow along. There should be nice QR codes and links for you to pull up, so please feel free to pull out your computer and try it out yourself. We have a couple of people running around the room giving out handouts and things. So if we're going through the tutorial part and you're running into an issue, raise your hand. If it's something that I can address for a bunch of folks, we have mics around the room too. They got a whole setup here, which is pretty fun. OK, without further ado, I think we can get started. So I wanted to, before we go over the agenda and really get into today, I wanted to just let us do some introductions, talk about who we are. So I'm Brooks Townsend. I'm a senior software engineer at Cosmonic, but I've been working on the project, WasmCloud, which is an application run time, application platform in the CNCF for the last little over four years. So I've been doing back end web assembly things since 2019, which is not the longest anybody's been doing it, but I've been doing it for quite a while. I have a passion for writing REST code and contributing to open source projects. I came from the Kubernetes background. I worked on a platform called Critical Stack, which also was open source, so my entire career has been open source things, Kubernetes, and cluster provisioning to running web assembly and working on a platform. So that's a little bit about me, Michael. Thank you, Brooks. So my name is Michael Yuan, and I started the Wasm Edge project in 2019, right before the pandemic. And at the time, we thought maybe the web assembly on the server era has finally become. But then we were hit by the pandemic, and we can't explain to people, web assembly is not really web and not assembly. It is what we call a lightweight runtime or container format that runs a new generation of applications. And that has been really a long road. My background, I came from Java. So 20 years ago, 25 years ago, when we did Java, it was a pretty straightforward thing. People would start adopting it, and then it sees a lot of commercial use. But the web assembly was three years of COVID that's in the middle. So that requires a ton of explanation and all that. But so the question that people have always asked me is that, where is the killer application? You always say, this technology is lightweight, it's secure, it's whatever. Every time you go on stage, you talk a big game. But what is the killer application? For the longest time, I find it's a little difficult to answer that question. But hopefully, in this workshop, we're going to show you something that, at least personally, I feel truly proud of. And I think you're going to also go home with some really interesting use cases that you can run directly on your own laptop by the end of this workshop. So please, it's an hour and a half, but stay until the end to do all the exercise, please. So yeah, I think let's go ahead and get started. So today, we're going to start on what is WebAssembly in parentheses abbreviated WASM. This is an intro level tutorial class, so I want to make sure we touch all the bases before we get started. We're going to talk about WASI P2, or WASI 0.2, which you may have heard of as the component model, if you've heard of WebAssembly before on the server side. And then I'd love to dive into what WASM looks like in Cloud Native. It's really important to make sure that we touch that base, and it's going to be both from the perspective of WASIM edge as a WASIM runtime, and WASIM Cloud is an application platform, both in the CNCF. We're going to do a few interactive demos slash tutorials. We're going to run through them up here while you do it. So you're going to write your first WebAssembly component based completely on WebAssembly standards and the WASI HTTP interface, and then be able to run and inspect it using, again, standard tools from the organization, the Byte Code Alliance, which is another standards body that works on WASIM. And then, of course, get to run some components using our runtimes and platforms. And then at the end, once you've made your first WASIM app very fun and it's great to extend that, we're going to go beyond that kind of hello world. Michael's going to do a great presentation of something that I think is incredible, the running LLMs locally using WASIM edge. All the code fits on a slot. Oh, wait, no. Sorry, I'm just spoiling it. And then distributed components using WASIM Cloud and adding capabilities in that way. So by the end of this tutorial, you should be able to understand WebAssembly and how it's different as a unit of compute from a container. You should be able to see how WebAssembly is a standards driven effort from the W3C to the Byte Code Alliance to the standards within the CNCF. And you'll deploy at least three WebAssembly applications and components, built using standard tools, running on the CNCF runtimes, using standard tools and practices. So let's go ahead and get on with it. So what is WebAssembly? I'm going to get a quick show of hands. How many of you have heard of WebAssembly or WASIM? Maybe more than just like, oh, I'm going to go to this tutorial. Oh my god, a bunch of hands went down for that. Wait, put them back up for the have you heard of it before? OK, I got ahead of myself. How many of you have used WebAssembly before? Everybody's hand should be up. Without knowing it, you have absolutely used WebAssembly as you've been navigating around the web. So I want to talk a little bit about the history, the high profile applications you may have heard of are like Photoshop on the web, Figma, Google Earth, Microsoft Flight Simulator. If you've watched a video on Amazon Prime, on your Roku or Apple TV or whatever, you've used WebAssembly before. So WebAssembly is all over the place, especially in highly distributed or highly different device or on the web context. And you have absolutely used it before. So for the folks who know anything about WebAssembly, I think it's probably be good to have the mics here. There are two set up here. What do you know about WebAssembly? I'm going to ask for volunteers just to say something. There's nothing too basic, but what do you know about Wasm? Don't be shy. I know that it's WebAssembly. There you go. And I know that in theory, in the very early version, you could compile something to bytecode that would be runnable using a JavaScript-based interpreter. I think it was by Mozilla, if I'm not mistaken. Excellent, yeah. You can compile code to an assembly-like language and then execute it in a JavaScript interpreter. Great. Any other takers? I'm not going to wait for you for too long. OK, then we will cover the bases. So WebAssembly originally came from Browserland, very descriptive name, assembly code that is running in the web context. It originally came out of this desire, like, hey, we have this huge code base across enterprises and industries in C, in C-sharp, in other server-side languages that we would love to be able to reuse in the web. Important things, things like encryption libraries that you don't want to re-implement in JavaScript or performance-sensitive things like single instruction, multiple data, make sure I don't get that wrong, like executing it quicker than just JavaScript can, at least, unoptimized in a runtime. So it came from this desire to have that. And in order for it to do this, in order to run code in the browser, it had to have many different things to actually exist as a technology. It had to be an open and standards-driven technology. Everything that runs on the browser is driven by the W3C, so HTML, CSS, JavaScript. WebAssembly is the fourth language of the web that the W3C works, maintains, and develops. It had to be completely architecture and OS agnostic. Of course, if you're running code in a browser, you can't have code that tightly couples you to a specific architecture or a specific Linux API. It had to be an instruction set that wasn't tightly coupled to those platforms that had to run in the browser. It had to respect the rules of the browser sandbox. You can't just have native code forking off processes and making HTTP requests on its own. So every single thing that a WebAssembly module, a WebAssembly binary does, it has to ask the host engine for. So if it wants to access the microphone, read something off of the page, it has to say, hey, can I please do this? It had to be a small binary. There was that really cool study from Google, released a quote from a few years ago that if your web page takes longer than three seconds to load, 50% of people will just leave. So you can't be shipping 100 meg binary around. It had to be a small binary. And because of this, it's inherently polyglot. It's an instruction set. It doesn't really matter what language you write it in. Just needs to be able to compile to the WebAssembly instruction set. So that's a little bit of a background on WebAssembly. And let's move kind of forward into how we got started doing server-side WebAssembly. All of these aspects that you hear for the browser land also sound great for server-side. And if you can think about in any particular way, I really like this slide. I feel like it represents the idea very cleanly. When you have a language, you write some code in a source language. It can be C. It can be Rust, Go, Python, JavaScript. You can use those language tool chains, some of them natively today, some of them using projects like ComponentizePy for Python or JCo, Componentize for JavaScript. And you compile it into a WebAssembly binary. That individual binary can run anywhere a WebAssembly runtime can run. It's not all unlike the idea of you have a container and you can execute it on a container runtime. Or you have Java bytecode and you can execute it on the Java virtual machine. I know some people don't like that analogy, but I think it's pretty apt. You compile to a platform agnostic bytecode and then you can run on the virtual machine. Now those Wasm runtimes, of course, they started out in the browser. And it's supported in all major browsers today. So you have Chrome V8, which executes JavaScript and WebAssembly, Mozilla SpiderMonkey, JavaScript and WebAssembly. It works in Safari too, also incredible. But now we also have this set of WebAssembly runtimes that works on the server side. So this is actually how Michael and I, we all got started. So we can just interpret this instruction set and execute it on a Linux box or a Mac or a Windows machine. So all of this came together and we started to take a look at the benefits of Wasm, like a tiny binary size, security by default, polyglot, open and standards driven. And we were like, wait, this sounds great for server side applications. Why don't we do it there? So from there came this idea of, hey, if there's going to be a standard for the technology, there also needs to be a standard for executing WebAssembly on the server side. So inevitably, in your application, you are going to want to do things like write to standard in, standard out, read from standard in, write to standard out. You're going to want to access the file system, open a socket. All of these things need to happen in order for your application to run. Can you imagine what you could do if you're a developer in the room? What can you do if you can't interact with the outside world at all? No databases. Nobody can call you. You can do Fibonacci. That works pretty well. But the idea is that in order for this to actually be successful, we needed a standard in order to work with these common constructs and applications. So WebAssembly system interface, aka Wasi, has been out with Wasi 0.1 for a long time. And Wasi 0.2 came out this January, so just about two months ago, with a set of standard interfaces that people can build their applications on. Comes with CLI, a set of CLI interfaces, file system sockets. And then the more higher level one for applications is HTTP. So all of these things, now that they are together, give different languages and different libraries the stable base to build WebAssembly libraries, to take existing libraries and port them to WebAssembly. And so you can execute these WebAssembly components kind of similar to the container standard. It's a standard set of packaging, essentially. And the key thing for this to be in the standard is that we needed to go through an open standards body process of proposing the interface, testing it, implementing it in more than one runtime. This is well battle tested within the different WebAssembly runtimes. So I mentioned the component model. And from here on, for the rest of the presentation, I'm going to refer to every WebAssembly thing as a Wasm component. For all intents and purposes, I think that's pretty accurate. You can think of it as a Wasm binary. But what a Wasm component is comprised of, this is actually the WebAssembly text format. So very kind of human readable, but assembly-like format. By the way, you probably would never write. It's just what you compile to, and then you can read. But you surely can if you'd like to write some assembly. What an actual component or a Wasm binary is comprised of is internal things. So on the direction on the right, there are things like memories, tables, globals, all the good things that you loved about your architecture class when you took it or when you looked it up online. And the thing that really makes it special is a set of imports and exports. So everything that a component is going to do, it has to ask the outside world to do. Or it has to be invoked by the host runtime. So this one import called logging. This could be something where you have a standard capability to log a message to some output. On the server side, we may implement this by dropping it to standard error. On the browser side, this may be implemented by outputting it to the console. So it depends on the local implementation, but you have to ask the outside host runtime to use it. So also, for example, if you needed to use something from libc, like forking off a process or doing a memory allocation, all of these things are not things that are natively available. You have to ask to use them. It's worth mentioning that this is not usually the level that you program at. So you have a set of imports. You have your core module on the inside, which is dealing with memory. It's all your assembly things. And then on the other side, you have exports. So these are functions that the host can call on your component. And you can think of all of this as very similar to like a foreign function interface, an FFI boundary. You can call functions, it can call functions, but it's very sandboxed and it's all done again with a set of standard interfaces. So it works well across different platforms, different runtimes, different environments. Now, as I mentioned, wasi.2 dropped in, says December, somewhere between December and January of last this year. An amazing thing that came with the component model is not just this imports and exports method, or this imports and exports concept. It's the fact that a matching import and export can be composed together. So if you have two different components that talk on the same interface, you can have them satisfy the other. So right here I have component A that's written in Rust, component B that's written in Go. And if they both talk using the same standard interface, think I wanna write something too standard out. And the other component can be reading from standard out. Then we can compose them together and create a composed component. Now this idea is really powerful because it allows both languages to interrupt in a way that they may not natively do so nicely. If you've worked with the foreign function interface before, it can be pretty dicey to get that to work. Have you ever tried to call JavaScript from C? Maybe, but this gives it a really nice, strongly typed interface to do it with. And you also get this idea of getting SDKs for free. So I don't know how many of you work at a company that has an internal project, or if you've worked with a client library before, you probably found the project and been like, oh, do you wanna work with Rust or Python or Node or Java? You pick your SDK and then you work with that. That whole notion of a language silo, those are all separate projects at companies like the company I used to work at. That was all actually separate teams that managed the SDK. That all now becomes one SDK that's written in the language that it's best for. If you're doing data analytics, maybe it's implemented in Python. If your number one priority is interoperability with Kubernetes APIs, maybe you wrote it in Go. But when you take that and you compile it to a component where the interface is what the SDK essentially implements, then when you write your component in the language that you like to use the best, you can compose them together, just like you would normally import in, bring in an SDK from the internet. It's a really powerful idea from composing components together. Now, if you are a security person in the room, you may be thinking, this sounds awful. I don't want to grab a random component from the interface and then link it together and give it everything that my application has, which is exactly what you're doing today, by the way, when you bring in an SDK. With WebAssembly components, what you have is a very strong boundary between these components. So even if you link them together, nothing is actually shared. You don't share the same memory. You don't share the same linear memory. Both of them are still actually separate entities. You just get to call functions on the different components. So it's called share nothing linking if you really look into the proposal. But all you really need to know is that you're still communicating over a very strong boundary. And this is not something that these function calls are not something that traverse a network. It's something that's been benchmarked and these function calls happen in the, you pay essentially a nanosecond, excuse me, level penalty in order to do this. So this is a very fast process execution. Now you may be thinking, okay, what about the interface? What is this import and export that I'm actually using? So the export of a WebAssembly component is a function that you need to implement in your code. And the import is a function that you get to call. So you would import things from SDKs and then you'll export something like an HTTP handler. And all of that is driven by wit, which is WebAssembly interface types. This cheat sheet that's up there on the screen is the one that I was talking about. It's the one that you kind of have passed around, but is an interface definition language, specifically built for WebAssembly. And there are a couple reasons why, but primarily it's so that we can have something that natively speaks the component language that we want. And we can use to generate types, bindings, functions in all of the languages that can support components. So in the interfaces that you write, we would write one interface to say, hey, this is how HTTP is gonna work. And then every single language can generate those bindings using either the standard library, depending on the level of support or the project called wit bind gen. And then each component, no matter what language is written in, is talking over the same interface. Now the cheat sheet, again, you won't need it today, but it goes over the types that are available, the syntax, and some of the things that you can do to define functions. So I can just a little bit more about interfaces. I know you all have the handouts, but this is kind of what an interface may look like. Versions can be mixed and matched. There is, you know, this is all really just to say that, you know, people have thought about this a little bit. We have different versions of interfaces. You can import multiple wasm cloud and wasm edge, both at least support the minimum preview amount of interfaces and WASI 0.2. And you can also just specify very specifically the imports and exports for your component. And I'll go a little bit more in depth on what this specifically looks like too, as you start writing the component and you look at a wit file. Looking forward just to continue to give you a little bit of context around what people have really been thinking about when they're starting on the component model. Each of these interfaces essentially come with a level of stability, how much they're going to be integrated into language SDKs. And as we move forward because these interfaces are so strongly defined, we actually have a notion of an adapter. So when there's new releases of an interface, even if they had breaking changes, you can seamlessly adapt your current application over to the new version of the interface. Now we have a set of standards, but that continues to grow. So WASI Cloud includes things like key value stores, logging, blob stores, WASI NN for neural networks, WASI Embedded for continually more embedded environments to run WebAssembly. And the new hot off the press WASI WebGPU. Totally highly recommend watching the WASM Day talk yesterday, I believe it was from the Intel folks who have been working on this one a lot. So this is all really just to say that there's a set of standard interfaces, but there's more being proposed all the time. And you can always write your own. So this is very extensible. As far as language support, there's very robust support for languages that can compile to like an LLVM intermediate representation. That's a little in the weeds, but you can essentially go to a WASM backend from there. So Rust, C++, C are all doing great in the WebAssembly support department, which is why you've probably seen so many WASM examples in Rust, JavaScript, TypeScript, Python, your Ruby, your scripting languages are essentially adding pretty solid support around taking an interpreter and then being able to run that code in WASM. And there's still definitely tooling coming out around Go, Csharp slash.net. There's more languages that aren't even represented on here like Zig and Ponylang. There's a lot of things that support WebAssembly, but of course there's too many things to put on a slot. So what does WASM look like in cloud native? And I promise I'm almost done with my spiel before we actually get into the good workshop content. So if you take a look at the CNCF landscape, there's a pretty big representation of WebAssembly across cloud native projects. There's a ton that use this for plugin models, for user defined functions, for proxy filters. There are different runtimes, different engines, different orchestrators. There's tons of WASM representation across the CNCF landscape. But we're here at KubeCon and what I really want to focus on is these are the projects in the CNCF that are like WebAssembly, runtimes, platforms, like this is why we're here giving you this talk today is because we've been running these things in a cloud native context for a long time. So I really wanna talk about how that fits into cloud native and how you can get started there. So I'm gonna go ahead and hand to Michael to talk a little bit about WASM Edge and where that fits into the cloud native ecosystem. All right, so we started as a WASM Edge project. There has been, like Brooke said, WASM is largely a standard. So a standard means multiple implementations. So when we started the WASM Edge project there has been multiple WASM implementations out there including in the browser and outside of the browser. So people ask, why do you want to start another project? It's because it's born from some of the use cases that we see at the moment that requires additional features and in particular we had the notion that we want to do something that is specifically optimized for the cloud native landscape meaning that's the common workload that's required in the cloud native space, the performance and also the integration with Kubernetes. So what does that even mean? So I know there's a wall of text about that, you know, but I'll try to explain through that, right? So the runtime itself is written in C++ but there's the most important application language on that runtime is Rust. So the thing is important because as many of you know, WASM grew up with Rust, they are both Mozilla project at one point. So you see a lot of WASM runtimes are entirely written in Rust, which is nice. However, we thought at the infrastructure level we need diversity in supply chain. You know, if there is a critical bug that being discovered in Rust it may bring down all the WASM runtimes, right? You know, so that's why from early on we decided to do a C++ based project and also because we are closer to each devices and hardware manufacturers as today WASM has used the, say automobiles and the factory floors and you know, things like that. And those things tends to be more friendly within their C++ header files and the C libraries. And one of the earliest things that we did is that we focused on performance. So, you know, we have both AOT and JIT compilers. AOT stands for ahead of time compiler. So people are asking us, you know, how much performance sacrifice do you have? You know, if I just compile Rust to native code versus compile Rust to WASM, right? We got tired of answering that question. So we wrote a paper and published it on IEEE computer a couple of years ago. The conclusion is that in some times compiling to WASM is faster. Okay, I repeat faster than compiling to native. The notion was so outrageous. The paper was originally rejected because the referee said, you know, the reviewer said, you guys must have made a mistake because what you have claimed is impossible. You know, that's how is that possible? You compile to intermediate format and runs faster than compile directly to the target format, right? So the reason is actually, I think pretty subtle and pretty interesting is that the AOT compiler compiles the WASM code to native code on the device to the runs. However, when you do the so-called quote unquote native cross-compilation, you typically just specify a generic device in that category. So for instance, if I'm compiling an application to run on say, you know, an Intel X86 device on a running Linux, but my compiler is on a MacBook, I probably would specify that target and then give it like the O3 compilation flag, you know, something like that. In that, it typically omits all the advanced features the CPU might offer. And as we all know, the CPU capabilities has improved significantly over the past couple years. So they have things like SIMD and you know, things like that, you know, there's lots of new instructions. But if you blindly compile to native, you typically target the lowest common denominator. However, if you have a WASM AOT compiler sitting on your target device and generate the native code from your portable WASM application, there's a non-strivel chance that the code generated from that compiling process is gonna be better than if you just compile to native, right? You know, so that's the reason for that. I thought that was pretty interesting because you know, you could say if I optimize everything native is still faster, but the point is most developers do not optimize everything. They just say I want to, on my Mac, I want to compile to x86, right? So give me a binary. And that binary is often sub-optimized. So that's, you know, so that's at the very high level, you know, that's we, you know, we are proud to be one of the fastest or WASM runtimes, right? So then as time goes on, there's more and more use cases. And also as Brooke has mentioned, there's lots of WebAssembly standards that's, you know, standard-rate WASI with components and all that. So we have thought that's, you know, it may not be a good idea to support all of them in a single binary runtime because that has security implications and also makes the runtime very bloated. You know, the benefit of WASM is being light, right? You know, it's being very small. So why do we want to pack all those features that we may not use? As we all talk about that in a minute, that as WASM being increasingly used in advanced field like AI inference, you know, which AI library, which GPU driver are you going to include with a WASM distribution becomes a challenge. You know, you can't just include all of them, right? You know, so a couple of years ago, we devised a plugin architecture. So basically the core runtime is just, you know, execute the WASM application, but all the operating system or the lower level interfaces with hardware and other drivers and the software can all be built into plugins. So for instance, in WASM Edge, you may want to make HTTPS or TLS core for external web services. In order to do that, you need SSL library. You need the crypto algorithm and all that. And we do not by default bundle that into WASM Edge and instead we have an installer option for user to install this as a plugin for users who have this particular need, right? So, you know, and because of that, we can, I think that aligns very well with component model because each of the component model proposals, yeah, from our end is now implemented as a plugin. So, you know, so we can have a large number of, you know, a very tight core runtime and a large number of plugins, right? So we have a rich set of features as plugins. For instance, we have asynchronous HTTP servers, you know, because one of the earlier server side of WASM use cases is to run as a service function or microservices. If you run as a microservice, you cannot have one incoming request to block the whole thread for extended period of time, right? You know, so you basically, even if you are single-threaded, you have to multi-task, you have to do, you know, a contact switching on that thread so that you do non-blocking IO. So, you know, so this whole non-blocking IO is not well-defined in WASI 1.0. And as Brooke mentioned, you know, the true native async actually comes in WASI 3, previous 3, right? You know, by the end of this year. But, you know, for the serverless use case that we have to deal with, you know, we have to build those functionalities into our runtime. You know, in a way that is, I hate to use a word that is not standard, but, you know, I would say it's ahead of the standard, right? You know, it's, you know, because they would have to reach that point at some, you know, because, you know, I think this is a non-negotiable feature, you know, when people build microservices or serverless functions. And like I said, build TLS for HTTPS clients. And, you know, there's also a WASM proposal called GC, you know, garbage collection. You know, this is one of those sort of things because when WASM first came out, we say we are lighter, we are better than the JVM because we don't have GC, right? You know, because, you know, our front-line language is rust. You know, the memory problem is being solved by the compiler. So, you know, we have no need for runtime active memory management like that. But as more languages started to target WASM, especially JVM class languages. So for instance, you know, one of the strong demand come from Kotlin community, right? You know, so they want to, you know, Kotlin is one of the JVM languages, like, look like Java and compare to the Java bytecode. But they also want to compile to WASM. So, you know, so they were the driving force behind the GC proposal to have a lightweight GC in the WASM runtime. But that creates a problem is that do we have the GC turned on by default? If we turn on that by default, then we can grow ever more complex that they become as heavy as the JVM, right? You know, so we did this with a plugin as well. So, you know, you can enable that feature on WASM Edge by installing that plugin and have that feature available to, you know, to the specific programming languages that you want to target, right? And perhaps with all those features, one of the results or one of the benefits is that most of the common Rust or Go, even Node.js libraries are now supported out of the box on WASM Edge. So for instance, if you use the Tokyo framework in Rust or you use, say, Hyper framework to start a server or you use Request.Vest to... You know, those are anonymous, popular Rust crates, Rust libraries, and you can just compile them to WASM and they would run on WASM Edge, you know, because we have, you know, the capabilities of asynchronous sockets and, you know, things like that. And so that's the feature related to the runtime itself. So that's the feature related to the runtime itself. And then another really big set of features are how the runtime is being managed, right? We say we are a cloud-native runtime. What does that even mean? You know, to me, that means the runtime itself or the workload can be managed by existing container tools. You know, so the way it works is that, you know, we build those partnerships through the CNCF community. We build this partnership with companies like Docker, like Red Hat, like Project like Container D, you know, over those years so that they can, to expand the capability of those tools to not only manage Linux containers but also manage WASM workloads. So at a very high level, it works like this. So you have an application that's written in, say, Rust or Kotlin or JavaScript. And you build it into a WASM file. That's going to run in WASM Edge or any other WASM runtime, right? And then you upload this artifact into, say, an artifact repository like Docker Hub. But instead of saying this is target for, the architecture is target for x86 or because it's neither, it's a WASM bytecode. It doesn't run on those CPUs. You treat WASM like a CPU format, okay? So you basically label this artifact to say the artifact is WASM32, you know, meaning 32-bit WASM binary. And so when Kubernetes, either container D or C wrong or, you know, one of the layers in Kubernetes goes into the container repository and fetch this artifact, it would know that it's not targeted towards one of the physical CPUs but targeted through the WASM CPU. So at that time it's going to bypass the Linux container bootstrap procedure and start using a runtime like WASM Edge or WASM time or other cloud-native WASM runtime to run it, right? So we have been quite successful in this area. So the article on the right is an article we just published, published on March 12th about WebAssembly on Kubernetes from containers to WASM, right? So it's a two-part series. It's a very, you know, I believe. So it's written by, I didn't write it. So one of our community members wrote it. I believe it's a very comprehensive introduction of how we can achieve, you know, WASM can run side-by-side with Linux containers in the same Kubernetes cluster and by working on some of the lightweight tasks. So for instance, you know, if you look at Kubernetes today, every single little thing is a Linux container, like, you know, wait for something to happen in the Linux container, right? You know, that container has 50 megabytes or 100 megabytes, why? Right, you know, all deployed EVPF agent, that requires a Linux container, right? You know, that's, so, you know, with WASM, you can do a lot of those things. You know, that's small things that, you know, happens. You start and once it's done, it gets shut down. You know, so it's more like a serverless or like a microservice type of approach, right? You know, so we are really proud in the collaboration we have, you know, we were able to do with the ecosystem projects. But, you know, that's, so, but one thing I really want to emphasize, you know, outside of all this, you know, our cloud native features or container features is what I believe a very significant use case for WASM today. You know, early in my talk, I talked about, you know, how people always ask, what's the killer application for WASM, you know? So I think now we know, because in the past year, we have seen more adoption in WASM than the past four years combined, you know, why? Because WASM solves a problem that hasn't existed in our space for 20 years since Java came along. You know, so I remember when Java came along, people also asked, what problem does it solve? You know, because there's a framework like CC++ that can write, you know, the server called Apache is because the server's name is a patchable server, right? You know, it's that you can use C to write, you know, Apache extensions and applications. You can, if you don't want that, you can use a Perl, right? You know, that's why do you need a new language for it? The problem it solves are two faults at a time, 20 years ago, two faults. One is that it's lighter than Perl. So it's faster and doesn't have so much baggage, but it's more portable than C. So that goes to write once or anywhere. So that allows developers to write application on their laptop and deploy it on the server without knowing the exact CPU type of the server, right? You know, so Java essentially solved that problem. That problem, we solved that problem with Java and then with Docker, with containers, with all that. But with the rise of AI and GPUs, this problem has come back with vengeance because we don't have a solution that can go across GPUs. If you look at, you know, even, say let's say NVIDIA GPUs, the QDA 11 is incompatible with QDA 12. It's incompatible with TensorFlow RT. And on the Mac, you have the different versions of Metal Framework. And then there's a new framework, MLX. And those are same hardware, just different software, okay? And then you have different hardware, you know, in the ARM ecosystem. There's NPUs, there's all kinds of different processes coming from different vendors. And then each cloud provider, AWS has one, Azure has one, has their own AI inference hardware and with associated driver. So it is now very far from guaranteed that if I compile application on my laptop, on my Mac laptop, I can somehow ship it and run it in the cloud. It's in fact, there's zero chance I would be able to do that, right? You know, so this potability problem has really come back, you know, because if you think about Kubernetes is not designed to recompile or even retest application before deployment. It's just designed to orchestrate and manage binary artifacts. So we need a new binary format that can go across the entire cluster from the local device to edge, to the cloud, and then to, you know, whatever the other devices that make this in that cluster, right, you know? So, and run the exact same binary application all the way. You know, so, and Wasm provide a potential way. And in fact, I think Wasm is the only way in the market that can do that. So thanks to a spec that called Wasm, which Brooks has also mentioned, you know, when Wasm first came out three years ago, Intel was the most important driver behind it. And most people didn't really think much about it. You know, why do you want to do AI in Wasm? You know, that's, isn't that what you should do with Python? You know, that's, so, you know, but now with all those problems of bringing machine learning workload to the cloud and to production, you know, there's, with this problem coming back, Wasm becomes a really good abstraction layer. So now Wasm is part of the component model spec proposal as well. So for developers, you only need to write and compile your application to Wasm. There's no need to worry about CUDA. There's no worry, no need to worry about the metal framework or any of the, you know, 100 different GPU drivers that you may or may not have on your computer, on your development computer, right? You write Wasm and you ship the Wasm binary. And then on the talking machine, if you have the Wasm runtime installed properly, it would be able to translate and dispatch your Wasm on course to the correct native course that's available on that machine. So we had CUDA 11, CUDA 12, you know, whatever it is, right? You know, so it is a very, I think it is a very nice solution that abstract away all the different hardware that's, that may exist in the cluster, right? You know, so that's why we say it's a new generation of write once, run anywhere, but for GPUs, right? So, and because of that, it's a, we can build a whole application developer platform based on Wasm, right? You know, that's to have, you know, nice APIs for developers to extend and to write their own applications. This is one of the things that I would hope to, you know, to cover as part of the workshop. So, Brooks, yeah. Thank you, Michael. Yeah, I'd love to take just a minute or two to talk about Wasm Cloud and what Wasm Cloud looks like as a platform and then I'd love to transition into y'all actually getting to write some WebAssembly on your laptop. So, let's go through Wasm Cloud. It is an application platform. It also comes with a WebAssembly orchestrator. We focus on declarative deployments. No matter what cloud, edge, or computer you actually want to run on. We integrate very, very well with the existing cloud native standards. So we use OCI Open Container Initiative to distribute all of our WebAssembly binaries. So you can just push it to a registry. We use the open application model standard for our declarative manifests. It kind of looks like a Kubernetes deployment. We're completely hotel observable. So logging traces, metrics, we got all of that in the platform and we package everything as cloud events. Just really want to nail in home that we're really into the WebAssembly standards, supporting that as a platform and very into the cloud native existing practices and standards that work really well and release solidly well today. Wasm Cloud comes with a set of standard interfaces, but it's extensible at runtime. And we use NATS, which is another CNCF project as our networking layer. So with that comes automatic load balancing failover and RPC for your applications. Now we are approaching 1.0, which is really exciting. And we are soon to be incubating in the CNCF. So Wasm Cloud is growing really, really well as a project. We've got a growing set of large and growing contributor community. So all of you folks who are looking to contribute to cloud native projects, please check us out. Everything is open source, of course. So you're welcome to, we love having more contributors. And we're getting a really nice set of growing industry adoption, which you could see if you watch the presentations that are actually up on YouTube now from Wasm Day yesterday. We had a few different companies from different industries, talk about their real use cases. So I think that will really help lend to how the project is going. All right, folks. Who's ready to write their first WebAssembly component? Nice, everybody's whelmed. I'll take that for now. So this is gonna be based on Wasi.2. So you're gonna use the standard HTTP interface in order to write this small application. And then we're gonna run it using Wasm Time, which is the bytecode alliances, WebAssembly, runtime. So we're gonna get started. I want to, everybody, feel free to scan the QR code. I realized after the fact that computers don't really scan QR codes. So the link is down at the bottom. It is github.com slash Cosmonic Labs slash KubeCon 2024 EU Wasm Workshop. I'll leave this up for a second as I give a spiel so everybody can, is everybody able to see that okay? Sorry, I can't see you folks. Just raise your hand if you're having trouble getting to the actual link and we'll have people come around. What we're gonna be doing during this tutorial is installing Rust and WebAssembly tools building an HTTP component that's written in Rust. You don't actually have to write any code. It's already there, so you can just look at it. And then we're gonna run the component with Wasm Time. Now I want to emphasize, because I talked about this a little bit earlier, that Rust has really great WebAssembly support. And that's awesome. And I know that not everybody is a Rust programmer or wants to learn Rust, and so this very first example is very Rusty, but the example that I'll do afterwards, you actually get to pick your language between Rust, Go, JavaScript, and Python. So everybody is welcome to pick their thing. I just wanna start from a common base. All right, please raise your hand if you need a little more time on the link, otherwise I will go look at it. Okay, so everybody I'm sure you will have a second to actually install those tools, but for now, well I guess you can keep looking at it. Everybody may take a second to install those tools, but what I'm going to do is run through the same tutorial as you, and folks are welcome to follow along at their own pace. So this repository has some instructions. So this will actually, I mean you honestly don't even need me. You can just go through the read me on your own. I'm just here, so let me soothe you as you go through this tutorial. So we're going to talk through this first example, and I wanna give a big thanks to Dan Goman, AKA Sunfish Code who set up the example that we're gonna clone and run today. It's a great Wazze HTTP example. And to start, you can either install these Rust things locally on your machine, or you're welcome to just run this in a Docker container if you prefer not to install some more stuff locally, and that's all fine. Just make sure to just take a look at those instructions for some libraries you might need. All right, so first step, we're doing this for real. So we're gonna clone the, why? Oh, I copied the whole thing. This is real. We're gonna clone the repository locally as hello wazze HTTP. And why don't we go ahead and take a look at some of the things that we're going to need in order to understand how we're building WebAssembly components. So I talked a little bit about wit. I'll make sure to zoom in a good bit here. Talked about wit, let's look at the wit. So this wit, this is the set of interfaces that this component is going to use. And what this includes is all of the interfaces from the wazze HTTP proxy. The keyword there is world, but you can just think of it kind of like your component in this case. So it's all the things that this component is going to use. Now if we take a look at the wazze HTTP proxy world, the really interesting bit is over here in the handler. Sorry, I guess my auto or my formatting is not showing up. But this wazze HTTP proxy handler includes one function called handle that receives an HTTP request and then you can write an HTTP response back. That's a pretty generic representation of an HTTP server. And that is the kind of level of interface that the wazze standard is working at. So you receive an HTTP request and then you can return one. Great. So that defines everything this component is gonna do. You know just by looking at this world that this component's never going to reach out to the file system or make a network request of its own. It's really, this is something that you can look at if you know the source code, but we'll talk about how to know about it if you don't know the source code in a minute. So in this project, you can simply build this by running cargo component build. And this will generate those bindings from the interface and then build a component. So if we use the wasm tools CLI, we can take a look at a components width, with component width, and look at the wasm 32 in the target directory, the wasm 32 wazze folder, and as hello wazze HTTP. Now this is kind of similar to the width that we just looked at, but it's kind of expanded and really laid out in fine grained exactly what this component is gonna do, which may interact with our standard in, standard out pipes like a normal program. It's gonna export wazze HTTP incoming handler, but that's it. You know if you have this component, imagine if this was untrusted code and you had no idea what was inside of it. You can actually take this and run it and know that it's never going to pull a file from your system, which is really sweet. Now I can talk about the code in a bit, but I think it's more fun if we run it. So we can use the engine wasm time to execute this component, and we can use the serve command in order to do that. This is kind of like my JavaScript background is failing me, like node serve, like isn't there a serve project or what I use, serve a thing? You know, something like that. You can serve this component, which implements HTTP. So we do target, debug, wasm, debug, wasm. We're serving this hello world component on port 8080, and we can curl this hello world component on 8080. Hello was the HTTP proxy world. So for all of you who are following along, you may be just a bit behind me with depending on what kind of tools you wanna do install if you did any container, things like that, but you can now run your first WebAssembly component. If we want to take a look at the code, maybe to do a little modification of our own, we can take a look in source and lib.rs, and if you're not a Rust station, if you haven't written Rust code before, don't fret, it works pretty similarly in every language because it's a standard interface. So we have a single function called handle here, and all we do as soon as we get a request is we just construct a new request to send back to whoever called it, and we write some string to it. So we can say something like hello, kubeconworkshop, yay. Now if we write that, and we run cargo component build, we get that new component, we can serve it the same way we did before, and you may not be surprised to know that if you curl it, you get the new string that you wrote, which is amazing. Everybody's written and done a hello world like this before, I think it's really important to start from the standard set of interfaces, get this hello world, and then you can kind of build from there. There's plenty of more information in this readme, so I would encourage you to take a look even past, even past what we do today in the workshop, but I wanted to call out specifically, like if you're looking at that code and thinking, man, I don't really want to write Rust, like what is this, like handler, like a request, there are some really cool tools coming out now that we have standards to build on, like Wasm HTTP tools, which is a project that takes open API specifications, like Swagger, and generates them from wit or to wit, so that you can basically take this, an existing open API kind of schema that you have, and turn it into a component. So you can kind of generate all that code and then work straight from that business logic, which is really, really nice. Okay, so with that, everybody has kind of written their first component and run it with Wasm time. There is definitely more to come, but I want to make sure that I can pass it back to Michael to present the, to present kind of leveling that up, so not just using HTTP, but really doing some cool things with Wasm. I think I have to turn on the mirroring. Which one? Hey folks, I want to make sure that Michael, you don't feel too, like you're good with getting set up. I know that we just hit you with a lot of information. I was wondering if folks had questions that they wanted to go over. Yeah, I think there's a mic actually right over there. You're welcome to go to it. Doesn't have to be about the demo or anything specifically, it can be on all of it. Thank you for the presentation first. Question about the memory management. If I'm building an application in CR C++ and I am a developer, which is the case, and doing things that are not supposed to be done with the memory, is there any protection provided by the Wasm runtime? Yeah, that's a great question. So when you're running your web assembly component, you can do nasty things still within your own little slice of linear memory. Like if you have your own memory and you try to go out of bounds on a VEC that you have or something, then more power to you. Your web assembly component will panic and explode. But web assembly does get its own isolated slice of memory within the Wasm runtime. And this is one of the reasons why the runtime is a key piece of this because it does protect from those types of memory attacks. Because you have your own slice of memory, it must not be able to overrun access of the memory and other components that are running in the runtime, et cetera. So you do get an enhanced level of security there. If you're interested in learning more, I would recommend checking out the Wasm time security audit that they did before 1.0, which I talked a lot about that. All right, a quick question, hopefully. You said that a lot of Rust crates can already compile to web assembly, like Tokyo and Hyper, what sort of examples you gave. But in the interface, I didn't have the time to look at the code properly, but I did not see Hyper being used or Tokyo being used. So there is still a difference between them or how do they interact? Yeah, it's a great question. So depending on the library, before Wasi 0.2, different libraries had support for compiling to web assembly using sockets, opening and making use of sockets. I'm sure Michael could talk about that as well because I believe they just implemented that. Now that we have a standard HTTP interface, that actually lays the foundation for all of these libraries to implement the HTTP functionality in a standard way. So the idea, it just came out a few months ago, so the idea is that the component model support lands in Tokyo or Hyper or Warp or Pick Your Language framework of choice. And then instead of writing in terms of the interface, you write a Tokyo application that listens on a port and serves a request. And that under the hood is using the Wasi standard API. Does that make sense? Yeah, yeah, perfectly. Thank you very much. Yeah, you're welcome. Okay, I think you're set up. Yeah, go for it. All right, yeah, thank you. Yeah, that's great questions, but it's a great, I think opportunity to represent Wasm Edge's effort in this standardization effort, right? So because component model is going to be an industry-wide standard and it's going to be supported by, you know, application libraries downstream. And so we should have not just one runtime implement that. You know, that's because most of the work is done within the vital alignings and the Wasm time team. And Wasm Edge and CNCF is our organization that supports this effort, right? So we are looking for their specs and implement their specs in our runtime as well. So we are committed to become one of the implementations that make it truly a standard, right? So the code I show here, and the link which you can run yourself, it's not as nice as the demo Brooks has just demoed, but it's the other way of HTTP, you know, he demoed serving HTTP page, right? But in this demo, we are demoing fetching HTTP page through the same component model interface, right? So if you're interested, you can have a look, but it's still a little rough on the edges, so you can see the code I have is a WebAssembly format instead of the raw Rust code because there are some ABI issues that we still have to support. So then goes on to the main tutorials that I have for the workshop, is to help you build a cross-platform large-language model application that runs on your own device, right? So I should be very cautious about this whole thing because the last time I did it in a large conference like that, it's immediately crashed the entire conference Wi-Fi because the large-language model is like, each of them is five gigabytes, although wasm is very small, but the models are big. So it's like everyone downloading a full-size movie, you know, so I end up not being able to get on the network myself, you know, that's not able to do the demo at all. But, you know, so I have all the instructions of the demo in the QR code, it's a GitHub repository. So what I would like to show you is I would like to do the walkthrough here. And if you want to follow along, that's your more than welcome. But I think it's more likely that you would go back to your hotel and do that at your leisure time and have a large-language model running on your own device in no time, right? So let's go to the, oh, sorry. Yeah, crash your hotel's Wi-Fi. Don't crash this Wi-Fi. Yeah, exactly. You know, there's, you know, people download movies on their hotel Wi-Fi. You know, that's no big deal. You know, that's a... So we have a installation script, a one-line script that is available in that GitHub repository. It's called the Lama Edge script. You know, so we have Wasm Edge and Lama Edge is the portable application we build for AI inference on top of Wasm Edge. So all you need to do is to run it. You run Windows, Linux, Mac. I'm running it on the Mac here, right? You know, so what it does is that it installs Wasm Edge first, although I'm not even downloading the large language model, but it's gonna take, I think, a minute or two to install, not only just Wasm Edge, but also the plugins that, you know, I talk about Wasm Edge has a plugin architecture that's all the unnecessary features or, you know, optional features available as plugins, right? You know, so large language model inference is definitely not one of the, you know, core Wasm features that we have to include with every distribution of this runtime, right? So, you know, so what we do is that we put it, we make it available as a plugin. So, you know, it's gonna, let's wait a little so that it's gonna download the whole thing and install the runtime. The runtime is about 20 megabytes, you know? So I want to compare this, you know, when people say, okay, you know, that's how, you know, it's 20 megabytes big or small. If you try to run this large language model with PyTorch, guess what is the Docker image size of PyTorch itself without the model? It's four gigabytes. Four gigabytes of applications without even touching the model, right, you know? So you can imagine if you want to run in a car. You know, that's, you know, that's, it would be, the cost would be astronomical, right, you know? So now it has downloaded all the, downloaded and installed Wasm Edge and it's very easy as you can see and it's skipped over downloading the large language model because it says, you know, it's, because it already have it. Now it actually has already started but I want to show back to see what it did, right, you know? So here you can see it's downloaded the large language model but it doesn't, because it's a couple gigabytes so it's skipped over. You know, this is a Gamma 2B model which was released by Google, you know, like last week and this is downloading the Wasm application. So this Wasm application use our socket API and use our large language model inference API so we build those API functions into the Wasm application. The Wasm application itself is only two gigabytes, it's only two megabytes and it can run on any device that has Wasm Edge installed. So I can run on Raspberry Pi and I can run on my local Mac and I can run everywhere. So, you know, as you can see here it runs and it start a server like Brookstead, right? You know, there's, we start an HTTP server and it starts serving it. What I'm going to do is I'm going to turn off my Wi-Fi so to make sure you see it that this whole thing runs on the local computer not on any sort of, you know, open API, you know, I'm not cheating in any way. Localhost 8080 it serves an HTTP page right from the, so, you know, so that's what I said, you know, one of the things you can do with Wasm you can start an HTTP server in it and it's an asynchronous server so it can handle multiple concurrent connections, right? So it shows you the library and, you know, things like that. So I'm going to ask what is the capital of France? Okay, we all know that but let's see if the computer knows that. So what this does is that it's a, by the way, my Wi-Fi is turned off, right? Okay, so this whole thing runs on this MacBook without even external power source, right? You know, so it runs entirely on its battery. So it says the capital of France is Paris, it's a political, economic, and a culture center of the country. What about Japan? So you can see it follows the conversation, you know. What do you mean what about Japan? If I ask, what about Japan? The first question, you have no idea what I'm asking, right? But since I already asked what's the capital of France, it knows I must be referring to what is the capital of Japan, right? So it tells me the capital of Japan is Tokyo. You can ask a longer question. You know, plan me a one day trip to Paris. So it goes back to Paris, it's gonna start to do those things, you know, start at FL Tower, it's gonna go on for a while, and sometimes it's not really right, you know, because it's only a two billion parameter model, so it's in the age of large language model, it's definitely a very small one, but as you can see, it's already spinning out words that faster than I can speak, right? So even on the, that's demonstrate, it's not only just running on the CPU, it's running on the GPU. What I haven't demonstrated here really is that I can take the same wasm file and use SCP, or use a flash drive, copy it to another machine that has the NVIDIA GPU, it would run at the same, at a similar speed with the exact same application would run the same way, right? So it's, yeah, so that's pretty long, right? So this is one of the demos, the first demo I wanna show you is that you have a wasm application, and then you can start an API server, that's because the API server is, I'm only showing you the web interface here, but you can also use the API endpoints, which I'm gonna show you in another demo. So you can have all the OpenAI tools available to work with this API server, because a lot of tools, assume it's connected to an OpenAI backend, right? This server on your local host can act as that OpenAI backend. So, but as we also mentioned, the power wasm is not just to stand up, say, API server, because a lot of people, a lot of tools can stand up API servers, right? You know, there's, I can think of quite a few. The power wasm really is the application development platform, so it can allow you to add features into the API server that is not available, that is addressing your own needs, right? So for in this specific case, I want to show you a quick demo of another one, that is, let me control C out of this, stop this server, and what's in the large language jargon is called the REG server. What is the REG server? It means I not only have the large language model in the inference, but I also have a vector database, and so I have some external knowledge source that injected into the vector database, so that when I ask the model some kind of question, it gonna go to the vector database and search for answer first, and then give that answer as a context to the large language model, so that the large language model can answer with better accuracy, right? So this is one of the, as you can see, there's a lot of interactions, and before we have this, if we don't do it in Rust and Wasm, we can do it in Python. That's where tools like LineChain, and Lamaindex, and things like that come into play, right? So they would just ask you to stand up API server and then use Python to do things outside of it, but the problem is that you have multiple Docker images, multiple Python installations, and each of them needs to be managed very explicitly, and then you would have very complex interactions between the model and the problem, and the data that you generate from the model and all that stuff, right? So with Wasm, we can write everything into a single application that is written in Rust or written in JavaScript, and then compile that into Wasm and have it within that Rust application to connect to the other sources. So it says it's recovering collection snapshot, meaning that I have external knowledge source that's about, that's knowledge source is about tourism in Paris. So I put that, I took a database snapshot and then ask it to recover, oh, okay, it's good. So, you know, let's see, fingers crossed to see if it's gonna finish. Oh, okay, so it installs FRP. Hopefully that goes fast as well, so it's one-third. So as you can see, there's multiple tools the Wasm application has to interact with so that to perform the complex orchestration of generating the problem, generating searching the database, and all that stuff, right? So now it's finished, it's finished installing, and I use another script to start it, start.sh, so as you can see, it starts the vector database first with the snapshot we gave it, and then start Wasm Edge with the large language model. What did it kill? Okay, so I think it's fine, you know, that's, so it's then to start a server. The server is not the API server we just wrote, we just show, it's another API server. By the way, all the source code is available. You know, that's, that's connected to the vector database before each query, right? So what I'm gonna do is that I'm gonna show you the log file so that we can see exactly what's going on with those. Start log.txt, I think that's what it is. Yeah, so the server starts, right? So I come back here, and I'm gonna load the local webpage all over again, and I can turn off my Wi-Fi here, but I don't have to, you know, so I turn off this, so here, it shows that it's now using a different model, it's using the Lama 2 model, instead of the Gamma 2D model, it's now a 7B model. So if I ask a question like where is Paris? Okay, so I ask a question about Paris again. What it does is that it's gonna search the vector database to find Paris tourism guides, and then use that as context to answer that question. I bet I can show, I can see that in the log already, so you know, so if you see in the log, you see I asked the single question, where is Paris? But the prompt that actually gives the LAM is actually this three paragraph of text. Those are the, what is search result from the vector database. Again, all of them is done using a Rust application that I compared to Wasam. Search the database, construct this prompt, and then send it to the LAM and for answer. So it's very clearly say, based on the provided context, Paris is located in this part of France, seated along the river, right? You know, according to the text, people live here for so long and so long, and you know, things like that. So you know, I would really encourage you to do those demo where you are in the hotel, you know, that's because I think it's, I'm just showing some very simple examples of chatting with it. A far more interesting case for all of us is to have it right programs. You know, today, we have a lot of Python, as you can imagine, a lot of the works that we do is to take those little Python program and translate them into Rust, you know, so that we can run those applications. I do none of this manually these days. I do all of, I ask the large language model to translate all of them. So whenever I see a Python program to pre-process data or tokenize the data, you know, something like that, I say, I need this in Rust so that I can build into my application server. I feed that into code llama and ask it to translate for me. And, you know, six out of 10 times, it's gonna, you know, it's gonna just run, you know, it's gonna just compile in the run. And sometimes it has, it needs some menu fix and you know, things like that. So it is a really very interesting productivity tool. So that's, I think that's my, oh, sorry, sorry, I'm sorry. Okay, let me, that's my demo. And I think, so yeah, if you are interested in the code, like I said, everything is open source and the basic inference code can be fed into one screen. It's less than 100 lines of code with Wasian as a target, you know. So we compile this code and then we, we, you know, we can copy it into Wasm and we can copy it around into anywhere. That's the Wasm runtime is installed, Wasm Edge is installed. So I'm gonna come back and send it back to Brooks to demonstrate some really interesting features about distributed components with Wasm code. Just, let's see if I can plug in a cord and talk at the same time. Just so you folks know, I did put all of these slides up on the schedule, schedule page. So if any of you folks want to actually take a look at some of the codes and the contents, you all should be able to, should be able to find it there. So all available, not that. All right, so for the second or for the third tutorial that you all will see today, what I really wanna go through is kind of extending that Hello World tutorial that I touched on before with logging, key value and start to take a look at what it looks like to take a component and distribute it across different environments, run the same component in different environments and do that using Wasm Cloud. So for folks who want to follow along with this demo, now is the time that you get to do your Rust or Python or TypeScript or Go. I'm going to use Go because I assume that the most amount of people have used that out of all of the things, but it all works the same, all the code works pretty much identical. So I would recommend just if you go, you can follow the same steps as me. If you go to wasmcloud.com and take a look at our documentation, I would recommend or you all should go through the installation part first, which is just getting a wash, which is the Wasm Cloud show, we're big on our puns, but what I want to actually run through is the quick start. So this is going to have a very similar beginning to the HTTP Hello World component. It's just going to be through Wasm Cloud tooling, which is by and large compatible or is compatible with the standard. So the first thing that we'll do to launch our local infrastructure is run wash up, very similar to Docker compose up kind of scenario. We launch our NAT server to handle our networking and we launch Wasm Cloud. Again, this is just a binary that runs on your local laptop. So it doesn't matter if you all are running Linux or Mac or Windows, it all works. I mean, that is a different binary, but it all works the same. So what we can do first, like I said, I'm going to use go and this is annotated tiny go just because of the compiler, but we'll keep going through there. I'm going to generate my new project, which is just kind of a, it's just a Hello World component. Actually almost exactly the same code that you saw before, just of course going to be in go rather than in Rust. So if we take a look at this, take a look at this component. I'll just open up in VS code to keep it easy. Oh, not there. Take a look at Hello. We can see it has this one go file here and that should be large enough. Please let me know if you can't see it well. But what this one file here has is a handle. It's the same function signature because it's the same interface that Rust was using. And what we do is set up a new HTTP request and we drop hello from go. Now the question earlier that came through about Rust libraries, the same thing applies for go. We're actually working on contributing the component model standard up to regular go and that should be slated to release in the next August release of go, which is super exciting. So in order to build this, similar to cargo component build, you can just run wash build and this will delegate out to go to compile this component. And we can take a look at this component just like we did before with Wasm Tools component wit. We'll see that it had a couple of new things come in but the important thing here is that we have the same export, Wasm HTTP incoming handler. And we can actually use Wasm time to serve this component. So if we run Wasm time serve as common build and then our HTTP hello world, I'll use multiple terminals, we can curl this. So this was a project that we generated and we built using wash but it just works in the standard runtime. Now what I wanna take you through next is taking this beyond HTTP. I wanna add some persistent storage and I want to add some additional logic to this application. So I ran through a couple of the steps in this quick start here. So you all should be able to kind of follow along. I know that we're kind of near the end of the workshop here so you can follow along at a more condensed or your own pace at home. But I want to go ahead and instead of running this in Wasm time, I want to launch this in Wasm cloud. So what we can do here, we have our declarative manifest which makes up an application which is just the local web assembly component annotated here as a component called hello world. And then we have one capability. This is an implementation of an interface. It's our actual HTTP server that we're going to run. So we'll go ahead and deploy this application. And if we take a look at our app, we'll see that it's reconciling, it's gonna download some things and then deploy. And now, if we call local host 8080, oh, where is that? Wash. If we take a look at this actual application, we can see that HTTP hello world is running. Let me make sure that's there. Give me one moment. I had some leftover things from my previous things of demo which is pretty fun. Okay, that will work fine. We're gonna go ahead and delete that and deploy it again. We already running that? Give me just a moment. So we're running the tiny go version. Okay, so we can check out that component that's running again, see if there's anything running and we can deploy that manifest again. This is what you get for trying to do the demo kind of at the last minute. The end of the workshop. Well, we'll give that a moment just to go ahead and spin up. What I really wanted to talk about as we get to the end is when you deploy this application, the kind of next step is, of course, as you're going to go on, you're gonna want to do more than just handle an HTTP request. And so this part, adding functionalities, really all about taking the standard interfaces for HTTP and for key value and for logging and adding those into your application. And the end of this just kind of walks you through taking this last part, modifying the code, making sure that you can build and update your component. And so I know that we are at the, kind of in the last minute and I really wanna make sure that I have enough time to answer your questions and go further. Of course, this is all on our documentation. I wanted to run through this live with you today. But I think I'll just go ahead and pause here and ask for any questions about the workshop today. All right, folks. Oh, yeah, go ahead. Yeah, thanks for your nice workshop. One question which came to my mind is, support for garbage collected languages or languages with dynamic typing. You said you have to bring your own garbage collector and configure it somehow as a plugin. How does it scale if I have a bunch of components? If I think about applications or package managers like MPM where you're boiling dozens of dependencies, how can I manage that at runtime? Yeah, so the WebAssembly, the proposal for garbage collection in WebAssembly is actually something that moves through the W3C. So it's not just something that's handled on the server side, but it's in the core WebAssembly specification. And that proposal actually landed in the W3C, so it's kind of a, the runtime can provide an implementation of a garbage collector. So if you do work on a garbage collected language, that does work. Now, I can't speak exactly to the internals of how it's gonna garbage collect for different languages, but I would highly recommend checking out that spec, the Wasm GC is the garbage collection, is the kind of working group and body there. But in the end, that means I need dedicated Wasm runtimes to support specific languages in the end. So it comes both from the Wasm runtime, which is just supporting the core WebAssembly spec, and then also in the language, the source language itself in order to put that logic there. Thank you. Thank you. All right, folks, I'm getting the angry caution. Don't be here anymore, sign. So thank you. We're gonna hang out here for a minute, as long as they allow us to, but we'll also be in the back as well. Yeah, go ahead. I got one question. I didn't quite understand about the difference between Wasm Cloud and Wasm Engine, since eventually we want to run everything that can run on a Wasm. What is the difference between the two runtime? If I do an application with Wasm Cloud, could it be run only for things that support Wasm Cloud? Yeah, so that's the exact reason why we have standard interfaces. The idea is that you write an application, you can do it through Wasm Cloud and everything, but if your focus is to work on like the interfacing with LLMs, Wasm Edge is the runtime to do that with. So then you can just take your application to the runtime that implements what you need the best. Yeah, so maybe I can add to that as well. So I think our two projects, what do we call it, a system project, a browser project, so I think we are upstream and downstream. In the Java jargon, you could see us, Wasm Edge as a JVM, and Wasm Cloud as an application server, right? So they have a lot more application-facing stuff. We are more focused on the runtime itself. Although we have application stuff that's built in, but we are aimed to be standard compliant, right? So going forward, we want to be one of the runtime that runs underneath Wasm Cloud. That's, so it's upstream downstream relationship, I would say, yeah. Thank you. Yeah, thank you. All right, folks, thank you all for coming today. I really hope that this was useful to learn about WebAssembly, actually get to run a thing, and looking forward to seeing you all at the rest of the conference.