 Hello, everyone, hi, my name is Michael. And I'm sorry I can't be here. I really want to be in this meeting person, but it's not meant to be. Anyway, so the title of my talk is Running JavaScript, Python, and Ruby in WebAssembly. So essentially running scripting language in WebAssembly. So since we are a technical audience, so I would just cut to the chase. When the hard started, WebAssembly was originally designed not to be a scripting language on time, right? You know, it's because we were unsatisfied with JavaScript performance. We want to run CC++ code, Rust code, and compiled language code, you know, with close native performance, right? You know, those applications are alongside JavaScript, you know, so that JavaScript applications can take advantage of that. So it's meant as a supplement to JavaScript. So as such, inside the browser, the WebAssembly runtime runs side-by-side with JavaScript, right? You know, so you have a JavaScript runtime and WebAssembly runtime. There is a bridge between them. And if you are writing Rust applications and compiling to WebAssembly, you would have something called the Watson-by-J. And if you are running compiling C applications, it would be something else. So essentially there would be a WebAssembly runtime with a bridge that goes to JavaScript. The JavaScript runtime act as a host for the WebAssembly runtime, meaning the WebAssembly runtime just run the computation. But the networking data file system and all that were provided by the JavaScript runtime and made available to the WebAssembly application through the bridge, right? You know, so that's the original design. You know, so the original design of WebAssembly really is to run compiled applications not to run a scripting language application like JavaScript, you know. So what has changed? So how it's going, you know, why are we talking about WebAssembly running, you know, JavaScript running inside WebAssembly now? Well, before we get to why, you know, let's see how it's done. You know, that's because, again, we are technical audience here, right? You know, so strictly speaking, it can be done, right? You know, because as we just talked about WebAssembly runs, applications compiled from C++ and Rust, and then, you know, although in the browser it's typically run side by side with JavaScript, right? But, you know, what is written in C++ or Rust practically everything, right? Including all the JavaScript, a lot of those JavaScript runtimes interpreters, Python runtime interpreters, Ruby runtime interpreters, those are all written in C++ or Rust. So they can be compiled into WebAssembly. Once you compile those into WebAssembly, you would have a WebAssembly application that then you can feed the JavaScript source code, Python source code, or Ruby source code to run them inside WebAssembly. So to run JavaScript inside WebAssembly, you do a nested architecture, you know, so you have a WebAssembly runtime on the outer shell and it has a compiled JavaScript runtime or Python runtime, whatever, what have you. And inside it, and as a WebAssembly application, and then you have, you know, different API modules to provide access, you know, like networking or, you know, we're gonna talk about those later. But then the scripting language application itself is feed into the WebAssembly application and get executed there, right? You know, so that's the overall architecture. So we know it can be done. And a lot of the content in this talk is, you know, we have that on our website. So the example applications and all that, so, you know, so if you mess it any good, you know, don't worry, that's, you know, the source code is available. And so, you know, we know it can be done, but why? You know, that's why do you need to run scripting language applications, such as JavaScript, Python, Ruby inside WebAssembly? So the reason really is because WebAssembly is growing in popularity. You know, people are, you know, because although it starts from the use case where the native, compiled native applications running inside the browser, it's now on the server side, on the edge, on mobile devices, on a lot of places. And people want to, you know, the traditional C++ developers or Rust developers are using WebAssembly. But new developers also want to use WebAssembly. And a lot of those new developers want to use JavaScript and Python, you know. So there has to be increasing need, I think in the last, maybe two years, that's, we have heard a lot from our customers, from our community, you know. How, you know, how they want to use JavaScript and Python and Ruby to a lesser extent in WebAssembly. Because simply because those are very popular languages. A lot of people know them, a lot of people know those, you know, to write, especially to write simple embedded functions. That's, that's ideally suited for WebAssembly. So next, let's look at some use cases of WebAssembly to understand why the scripting languages are so important. So here are some use cases, you know, we touched on them casually, just, you know, just now. So the first, of course, you know, it's what WebAssembly has been very successful is to extend existing applications with user defined functions, you know. So you have applications that really need any number of languages, you know, REST, C, Java, you know, whatever. And then you want to turn your software into a platform, into a pass, right? You know, by allowing your users or other people to customize it by adding their own functions to your software, right? You know, essentially turning your, you know, this is what we call application serverless, right? You know, that's, you know, adding some, so for the user to add serverless functions or user defined functions into your application and to customize it to do the job that they want, right? You know, so in that case, the user, the application itself may be written in, say, Rust or Go, you know, whatever. But the extension functions or the serverless functions is oftentimes written in a language that is local. So, you know, JavaScript and Python are, I would say, you know, fairly popular languages that people want to use for this particular use case, right? And then there's each cloud use cases. I mean, you know, that's, you know, for instance, the compute nodes on CDN networks or, you know, 5G MECs, you know, those are data centers on the edge that outside of the cloud, big cloud data centers that are closer to the end users. And, you know, so there are a number of application use cases there, so for instance, there's isomorphic rendering, you know, so meaning the server-side rendering of React or server-side rendering of popular JavaScript frameworks. You know, today, you know, those are rendered inside, say, Node.js or Dino running inside Docker, right? You know, all inside of VM. And it's a way to run those JavaScripts in a lightweight environment such as WebAssembly. And there's AI inference, right? You know, so you have, you know, pictures or other data captured by edge devices and it's, we are economical to send it all the way back to the cloud data center to process them. And we can process them right on the edge, in the edge cloud and, you know, and have the results stored there or have, you know, generated actions from there and, you know, things like that. And then there's edge devices use cases. You know, because WebAssembly is a lightweight runtime, so it can run on mobile devices as a cross-platform runtime, essentially replacing the JVM in a lot of cases. So you can embed a WebAssembly runtime inside a mobile application. Like, like, Avalon has done with Avalon Prime Video, you know, that's how they have, those video players, they have, it needs to run, you know, C-based, you know, applications. And in order to simplify the work to run the C-based applications across, you know, according to their blood, over 8,000 different devices types, you know, all kinds of Android devices and iOS and, you know, things like that. And so they need the middle layer that provide cross-platform compatibility and WebAssembly with ability to, you know, WebAssembly would be, you know, one looks ideal, you know, runtime for this purpose, right? So, but in this case, WebAssembly not should not only be able to run, say, C or us compile native code, but should also be able to run, say, you know, JavaScript and Python, things like that. And then last, you know, there's, you know, there's a very big set of use cases that we have seen, we've probably seen today from this, from the cognitive wasn't there, is that, you know, a very interesting use case of WebAssembly is to use it as a standalone container, you know, directly managed by Kubernetes, right? You know, so you could have a, you could have a service mesh that has, you know, Docker-based or Linux-based services and, but also have WebAssembly-based services. And in this case, you know, there's a, you know, for a lot of computing tasks, we especially embedded computing tasks, you know, Docker-based containers could be too heavyweight. And so, you know, we want to write the service, we want to write the microservices in WebAssembly. And in this case, you know, JavaScript and Python both provide very, you know, compelling, you know, service frameworks for, you know, for running those microservices. So those are the reasons why, you know, the use cases, why do you want to run JavaScript or Python inside WebAssembly? So for today's talk, you know, we're gonna spend perhaps, you know, most of the time talk about JavaScript, you know, because that's, like we said, this is one, this is the most important use case. And we're gonna talk about Python and Ruby at the end of this talk. So the way to run JavaScript inside WebAssembly, like I've just said, is to take a C++-based JavaScript interpreter or JavaScript runtime engine and compile it into WebAssembly bytecode and run as a WebAssembly application, right? You know, so this is the work that people have done, you know, that's what we have done this as well, but, you know, the community, you know, you know, have supported one of the, you know, most lightweight and quickest, you know, JavaScript interpreter called QuickJS into WebAssembly. So as you can see the example here, it's by leveraging the WebAssembly WASI standard, meaning that, you know, to have this QuickJS runtime running inside the WebAssembly runtime in this particular case, the WASI managed runtime, it would have access to the operating system, it would have access to the command line argument, for instance, and it would have access to the local directory. So it would be able to read files and read from the command line, you know, basically run a very standard JavaScript, so it can, essentially you can put any JavaScript content here and be able to run it, right? So that's, you know, that's the basic stuff, you know, that's to have a QuickJS runtime compiled into WebAssembly to run any pure JavaScript content. And with this, with QuickJS, it's, you know, it's very easy to have, you know, ES6 module, you know, so meaning that's now we can, you know, with a QuickJS runtime inside the WebAssembly, you know, inside, say, WASI managed, it can have access to the operating system, so it can read multiple JS files, right? You know, so you can now have, you know, ES6 syntax to, you know, to export and import functions across different files. You know, so here is example, you know, so at the top panel, you have an exported function called hello, and then you have on the top panel, on the other side, you have an asynchronously exported function and also a variable string, right? And then, you know, in the middle panel, you have, you know, the JavaScript application that imports the, you know, the ES6 modules because the imports was imported from the file system, so it could be a synchronous operation. It could also be a synchronous operation, right? You know, so it depends on the syntax flavor that you want to use. You could do it asynchronously or synchronously. And so both are fine and we want to demonstrate both use cases. And then, you know, using the QuickJS runtime, you can load this and run it inside WebAssembly and you can see the results here, you know, that's, you know, it would be able to execute, it would be able to import those functions from those modules and execute them, you know? So that's a very simple example of, you know, how to run ES6 modules inside WebAssembly. And so ES6 module is a relatively new standard for JavaScript. For a lot of older JavaScripts, you know, especially the ones that in the Node.js ecosystem, we are still using the common JS module, the CGS module, you know, there's lots of JavaScript libraries are written in that way. So in order to use CGS, we have, we use another tool called, called ROP. So, you know, that's essentially, you know, there's, you use ROP.js to package a JavaScript application that imports those MPM modules into a single file, you know, that's essentially it takes down all those, it's post down all those module files from MPM repository and then combine them into a big file. And then, you know, you can use WebAssembly, you can use the quick JS environment inside WebAssembly to run the entire file, right? You know, so that's, you know, so we also have a demonstration here, you know, that's basically it takes the, you know, the digital signature module and then computes MP5. And it's also, that's one, you know, takes one of the master libraries that computes that. So, you know, so those are, so, you know, through ROP.js, we can also support, you know, common JS modules and a large part of the MPM ecosystem, a lot of MPM modules can be supported this way. But if that's, you know, if we just to support ES6 and CGS, there will be, you know, it'll be interesting, but perhaps not yet compelling. And what I find most compelling that adds new features to, you know, to running JavaScript inside WebAssembly is really to, is to allow Rust based implementations and WebAssembly and JavaScript to interact with each other. Meaning that, you know, you could have, you could write a function in Rust and then expose this function as a JavaScript API. So as a JavaScript developer, they would not need to know the Rust implementation behind it, they would just need to call the API. So a lot of this API is provided by QuickJS itself and our Rust wrapper is around QuickJS, right? You know, so on the left side, you can see there's a Rust function that is, you know, designed to interact with JavaScript so it has constructs like the JS function and JS value and things like that. And then on the right side, is that we, when we compile the QuickJS runtime, we now have hooks to import this function. This function is a struct called flowfn, right? And give it name, you know, in the context give it name called hi. So then we run a JavaScript, you know, then in the JavaScript, we can simply refer to this function as hi, right? You know, so the JavaScript code is, you know, it's on the right panel, it's code equals to hi, one, two, three, right? You know, that's the, so meaning in JavaScript, we just call hi, one, two, three. And the JavaScript interpreter sees the symbol, knows it's a building function that it can find its implementation in Rust. So it goes to Rust to find this implementation and execute this function and then give you the result, right? You know, so, you know, on the right you can also see the result from this. So, you know, why do we do that? The way the reason to do that is that, you know, so for the, for a lot of tasks that pure JavaScript kind of slow or it's difficult to do, you know, so the ability to have the ability to use, to write those tasks in Rust and then have the whole thing compiled into WebAssembly allows us to mix the ease of use of JavaScript and the high performance of Rust, right? You know, that's really taking advantage of WebAssembly's capability to run both, right? You know, to be able to run, you know, Rust compiled applications and also JavaScript applications as interpreter, right? You know, so I think this is one of the, you know, compelling cases of why you want to, you want to run JavaScript inside WebAssembly because you could potentially run faster and safer, right? So with that in mind, you know, so we, you know, I want to introduce you to some, some of the, you know, Rust APIs that we have already built with our, you know, because I work at, you know, I'm the main internet at Wasm Edge, you know, so at Wasm Edge we have some Rust extensions, SDK extensions to WebAssembly, you know, that's, so we built some of the functionalities as JavaScript APIs using the approach that I have just mentioned, right? You know, so for instance here, that's, you know, as we know, a networking socket has been a long missing feature from Wasm, but at Wasm Edge we added our own non-blocking asynchronous networking, you know, socket support, right? And we have a Rust SDK for that. So in our QuickJS implementation, we have, in our QuickJS setup, we have, we have a Rust module that implements HTTP module inside JavaScript. So meaning that when running QuickJS inside Wasm Edge you could write JavaScript that does HTTP request and does HTTP, and become HTTP server as well. As, because HTTP server could be asynchronous, meaning that it's non-blocking, right? You know, it can handle multiple concurrent, you know, connections at the same time from the same port, you know, using the same thread. You know, so there's, so by incorporating the Rust-based IO library that Wasm Edge has provided for its WebAssembly implementation, we would be able to support, you know, networking-based JavaScript applications in Wasm Edge just using the techniques I've just mentioned, right? That along the same line of thought, you can, we can do the fetch API, right? You know, we can do HTTP, because we can do simple HTTP request and the HTTP server. So we can do the fetch, you know, that's, we're gonna talk about the significance of this API in a couple slides. And you can also do the, you know, one of the interesting features of Wasm Edge is it provides extension for TensorFlow. So it also has Wasm and extension for OpenWinder, you know, meaning that's, you know, you can use Rust to write AI inference applications and have them compiled into WebAssembly and runs inside of Wasm Edge. You would know to use the GPU or to use other, you know, hardware or software components available on the device to do the AI inference. And because this is a Rust API for that extension, we can also incorporate that into JavaScript API using the technique I've just mentioned, right? So here is an example of JavaScript application that you can run inside of Wasm Edge to take advantage of the TensorFlow extension. So now we have talked about, you know, that's, we have networking, we can have, you know, those native functions inside of WebAssembly. So one of the, when we combine those together, one of the more interesting things that we can do on Wasm Edge is really to do server-side rendering for React applications. So in React 18, there's a way to do server-side rendering for streaming SSR and the way it works is to fetch the data from other servers first, build the model and render HTML and then send the HTML across the wire to the browser to do and then be rendered as a UI in the browser, right? You know, so this whole generating the HTML DOM components and the rendered content intakes, you know, can all be done on the Edge server, you know, inside of WebAssembly runtime now. So in the past, you know, you have to have Node.js or Dino and then have them wrapped inside a Docker container to do that. You know, now we have, you know, now we have a WebAssembly runtime that is much, much faster, that is much, much smaller and almost as fast, right? So there's an example website and tutorials that you can try on your own, you know, so you can take a React 18 application and make little changes to how the SSR server is run because you are no longer using Node.js, you are using, you know, the non-blocking socket in the browser match. So there's a tiny bit of code changes there and once you do that, you know, you will be able to launch it and run it on your Edge server. So, you know, now, you know, one of the common questions I get is, you know, when you're choosing Quick.js, you know, how does that compare with V8? You know, that's because V8, behind Node.js and Dino, the high-performance JavaScript engine, can you be as fast as V8? The answer is no, Quick.js is the interpreter. It's, it doesn't have GIT, so it's much slower than V8. However, as we said, you know, one of the things is that a lot of those bottlenecks, like, you know, a huge time-consuming, you know, tasks like generating strings, you know, AI inference, and you know, say, a network, concurrent networking and all that stuff, it can be done in Rust. You know, so you don't have to do that in JavaScript. In that case, you know, the overall performance of application may not necessarily be much slower. You know, just, of course, the true benefit of using Quick.js and WebAssembly is that it's much, much smaller. So V8 is like 40 megabytes in memory, but Quick.js is like less than one megabyte. So even adding WebAssembly is still much smaller than, say, you know, V8 inside Docker, right? You know, and Quick.js in WebAssembly is also safer because the WebAssembly runtime itself is a security sandbox and it has much smaller attack surface for, you know, for security issues. And it's also more manageable, you know, because WebAssembly runtime itself is OCI container and it can be managed by Kubernetes. And the thing, you know, in order for V8 to do that, you have to wrap it around in a Linux container, which make it much, much bigger and heavier, right? You know, so of course, there's other approaches to run JavaScript inside WebAssembly. You know, one of the leading alternative is SpiderMonkey. You know, that's the JavaScript engine, the Jet JavaScript engine that's used in Firefox. So there's articles and also code how to do that. And then there's Shopify has a project called Javi and it's also a set of Rust wrappers and tools around Quick.js that Shopify has developed, you know, that allows, you know, pretty much, it's a similar approach that I've just described, so check it out. So the other way to do it is really to incorporate V8 into WebAssembly using V8 as a host function, you know, meaning that it has JavaScript evaluation directly into V8. But that's something, you know, that's something that we are experimenting with and, you know, if you're interested, you know, we could talk more after this talk. Yeah, so, you know, that's the thing about WebAssembly, now we have a couple minutes left, so we want to talk a little bit about Python and Ruby as well. So for Python, you know, so for JavaScript, we took a JavaScript interpreter and it compiled into WebAssembly. We can do the same thing for Python. So Python, there's a Python interpreter written in Rust, right, you know, it's called RustPython. You know, so you can take that project, you can take that project and compile into WebAssembly, into WASI, you know, using your Rust compiler to do that. And then you can just run, you know, a Python command shell, you know, you can run any pure Python applications in there, right. However, you know, that's, you know, there's still a lot of work that needs to be done because most Python applications out there are not pure Python applications. Those are Python wrappers around C applications, you know, it's pretty much, you know, the same approach that we have just described, and you know, we have JavaScript applications wrapped around Rust applications, right. You know, so they cannot simply be interpreted by Rust Python because they have native libraries. And however, those C libraries could potentially be compiled into WebAssembly as well, you know, using the same approach that we have just described with JavaScript. So this is pretty much, you know, a very exciting area that's, you know, I think people should be working on. You know, of course, there's, you know, because the networking acts socket support in WASI is lacking. So we can't quite do Python networking applications yet. We have to incorporate, if we want to run the WASIM edge, we have to do, we can incorporate the WASIM edge socket API into Python. And then supports Python frameworks like Fast API to turn that into a microservice framework, right, you know. So there are things like that. You know, so, you know, that's a, that's a still pretty much working progress and we'd love to collaborate with the community. Then there's another interesting approach is just to compile Python to C, right, you know, turn the Python code into C code and then turn C code into WebAssembly and run inside WebAssembly runtime. So that is another, you know, interesting approach people have been trying that. But, you know, we can also see some roadblocks because, you know, primarily because, you know, not all C APIs are supported in WASI. So you're going to find some things that are missing. And, you know, so basically you might vary using this approach. And then one of the exciting, you know, happenings last year was the Ruby team, the C Ruby team has figured out how to compile the C-based Ruby interpreter into WebAssembly. So they even provide a very simple tool for that. You know, so from their repository, you can just, you know, compile, you can compile that and run that team as much and you would be able to, you know, run Ruby, pure Ruby applications that way. Of course, you know, that's, you know, Ruby has more language features than WebAssembly can support. For instance, that's thread, it has operating system processes and, you know, things like that. So all those things has to be, you know, worked out before this can be a generic Ruby runtime. So yeah, that's, you know, you know, we have gone very quick overview of, you know, of scripting language support in WebAssembly using WASM edge as an example. You know, that's, and like I said, JavaScript is probably the most, the one that has most application, but also the one has the most mature support. And, but Python are getting there, you know, I think, because there's lots of Python developers and lots of people are interested in that. And there's a clear roadmap of, you know, adding more features to both JavaScript and Python, you know, to have them run better in WebAssembly, right? You know, and Ruby is not far behind as well. So, you know, I think hopefully by this time next year, by the cloud wasm day next year, that we would be able to see a whole slew of, you know, scripting language applications running inside WebAssembly, user running inside as serverless functions or as extensions for other platforms, you know. So thank you very much. So I think that's all the time I have. So come check out WASM Edge and I'll talk to you later. Thanks.