skip to content

Run Go, Rust, and more in JavaScript using WASM + Extism

We can build cross-language applications that can use Go, Rust, Node, PHP, .Net, Ruby, and many other languages through the power of WebAssembly. Steve Manuel will teach us how we can do it quickly using Extism.

Full Transcript

Click to toggle the visibility of the transcript

Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON: Hello, everyone. And welcome to another episode of Learn with Jason. Today, on the show, we are going to learn about WASM and how we can actually use it even if it's been something that's intimidated you, and to teach us, we're bringing on Steve Manuel. Steve, thank you so much for joining us.

STEVE: Hello.

JASON: How's it going, Steve. Thank you for joining us.

STEVE: Super excited to be here.

JASON: I'm very excited to be talking to you because WASM is one of those things that I have been looking at forever. I think it is really cool, and it just scares the pants off me. So I'm very excited to learn about that. But before we talk about that, because I have a million questions, I want to talk to folks about you. Can you give us a bit of a background?

STEVE: Sure. Yeah. I'm a software engineer, entrepreneur, you know, I have kind of done startups for a long time. Worked for companies big and small, some of which you may know, fanatics, Cloudflare, worked on the workers team to build up the Edge platform, one of the first kind of deep experiences I had with web assembly and kind of one of the reasons why started a company to focus on web assembly and built this framework, which we'll get to talk about today to make working with WASM easier. Because, frankly, it's a bit of a low level technology and it can be challenging to get started with. And so, yeah, I'm just, you know, a programming language fanboy, I've worked on compilers and distributed systems for the majority of my career. And, yeah, just love writing code and software and everything about it. And WebAssembly, to me is this next phase of virtualization. And it's a very exciting time to start looking at this technology because it's going to have a pretty big impact on the future for software developers.

JASON: Yeah. Absolutely. So, let's talk a little bit about like WASM in general is very cool. So if I can I'm going to attempt a definition and make sure I'm right. So my understanding of WASM, which is short for WebAssembly. It's a way for us to take roughly any programming language or at least a wide swath of programming languages and then compile them down into Webassembly giving us an executable file, which means we can run it on the web. So it's sort of like saying, hey, Rust or PHP or Go, build yourself down into this .Wasm file, and I'm going to run execute some Go code in the browser. Is that roughly correct?

STEVE: Yeah. 100%. Everything you said is true. There are a couple of other details that are, I think, important to call out. But yeah, the high level story is exactly that. Let's take code written in practically any high level language, anything above Assembly and create a new target for that code to compile to. So we're used to compiling code to something like X86 or ARM instructions that are specific to a chip. And WebAssembly is a new format, a new instruction set architecture that allows the languages to compile to. And it a also is a virtual machine where the ISA can be executed. And the cool thing about this virtual machine was that it was designed for the browser and it's going to initial home was to sit inside your browser running that code next to your JavaScript code. But it has since broken out of the browser to be a very useful runtime elsewhere, including desktop applications, server apps, CLIs, blockchains, virtually anywhere you can run WASM these days. And so it's a very interesting technology for portability, but it's also an interesting technology for security. And because it was designed to live in the browser, you know, basically had to design it with, you know, to live inside the most, you know, risky, hostile environment possible. You're downloading code from arbitrary places every single web page you visit. And so, you have to have a very high security posture around the virtual machine that executes the WASM code because it could come from anywhere. And because of that, you know, WASM itself really can't do anything. It's kind of an overengineered calculator. And so the host that runs the WASM code embeds the virtual machine actually has to provide it all of its capabilities, besides computing. So if you want to reach out to a network or read a file from disk, read an environment variable from the host system, the host actually has to grant very explicit capabilities to the WebAssembly virtual machine, otherwise, it can't do much on its own. At face value, a limitation, but really truthfully, that's one of WASM's greatest strengths, it can't do anything unless the host system tells it it can.

JASON: Yeah, that does seem good. Because that, like so using that, it's sort of impossible to get WASM mal ware unless they can socially engineer you into giving permission to run it? Is that correct?

Look at the relationship this website wants to use your microphone. Will you allow it permission to do that? This website is trying to read your location. There's this permissions based capability system on top of the browser that ensures the user, I'm not going to do anything unless you tell me it's OK. It violates the expectations of what a browser should do, which is load a page, execute the code, render it. So beyond that, when it exposes you to system of resources, it's going to make sure you're OK with that. While all of this is programmatic, largely, when a WebAssembly module runs, it's not asking, can I do this? When it's finish if it doesn't have the host to make the call of the network, it won't be able to run.

JASON: Got it. Very cool. Very cool. So this is, like, thinking about this in the context of the browser, there was a joke in the chat that kind of got me thinking WASM is sort of the spiritual successor to Java applets?

STEVE: Yeah, with the caveat it has a security policy. Java and Docker and every run time that runs code is by default going to let the code do whatever it wants. If you've gotten this far, I have your code, I'm going to run it. Whatever you wanted to do, I'm going to do it. And that's usually the intent. I manage my own server, I'm running the Java virtual machine there, I load the I want it to run.

It's like, you knew the password. You said public static main void, you're in.

STEVE: Exactly. You're in. We found a lot of cases where that's not ideal. While, yes, it is correct that the JVM and, you know, Java byte code, the description of the instructions that can execute in the JVM are spiritually aligned with WASM. It's really this notion of the security that WASM provides that is very, very different and enables a lot of really interesting use cases, one of which was the reason why we created Extism to begin with, which was for plugins. I want to be able to run code that I didn't write that's untrusted securely with high performance inside my application without destroying the security of my system, without giving this arbitrary third party code full access to the memory and the pointers and, you know, the functions inside of my app. I want to carve out a little box for it to live in, it can't reach out of that box, and it's only going to be used when I put in that box to do arbitrary code execution for things like extensibility and plugins, Extism was designed around the use case. People have started to use it for all other kinds of things, which is exciting, but the unlock that WebAssembly's security model provided, you can run untrusted code in process, inside your app.

JASON: Hmm.

STEVE: And WebAssembly makes that reasonable to do.

JASON: That's very cool. So, the followup question I have, then, is less about the what of it and more about the how. Because when I start thinking about WASM, everything that you just said sounds very cool. And also is sort of overwhelming. Because when I start thinking about, OK, so first, there's I've got to have code that I want to turn into WASM. So I'm already kind of thinking about now I've got some Rust or Go or something like that, and then, I have to know how to turn that into WASM. And then, I have to know how to put it into this parallel machine alongside JavaScript, and then, I have to know how to make those things talk. So ultimately, that sort of led to me having, I think, not intentionally, but a little bit of a default stance of WASM is a really, really cool thing that I hope somebody else uses really well. Right? [ Laughter ] And so, I, as somebody who, you know, I wrote a bunch of PHP 10 years ago, but around 2015, I took a hard left into basically like JavaScript land. I write Node on the backend, JavaScript on the frontend. How does somebody like me take advantage of this? How do I actually start using this?

STEVE: Sure. The truth is you're probably already using it, certainly in your day to day when you're browsing websites or using apps. There's a lot of WebAssembly running in those codebases. It's usually hidden behind the scenes, just like wrapped inside of an NPM module and you don't know any better, but it's you know, able to run more high performant code for you inside the JavaScript environment.

JASON: I think one of the prominent examples of that is Figma, right? That was the big bet, they were going to run a lot of their graphic stuff on

STEVE: Absolutely, Figma is a great example of this. Super high performance, heavy math for doing busier curve calculations and all kinds of other, you know, high compute requirements inside the browser. And they just have a lot of C++ code laying around they were doing the run that code get good security. There's a win/win situation and benefitted tremendously from it. But other interesting use cases, for example, the photoshop team, Adobe released photoshop built on top of WebAssembly. Shopify's a good example for a different modality, running WebAssembly on the server where they wanted to provide their customers with even tighter integration into the Shopify platform. You can't just give me arbitrary third party kind of developer access to the Shopify database or the Shopify codebase, which is, you know, largely and Ruby and Rails application, everyone knows Rails who want to write JavaScript or Go or Rust or whatever. And Shopify was pretty early on this trend to say, hey, we can give these hooks directly into our application that will allow a user to write some code, ship that code and run that code when these hooks are activated. So for example, when Shopify user goes through a checkout flow, I want to create a very customized coupon code or discount and apply it to that one customer. But I don't want to create, like, 10,000 different versions of this coupon to apply to all of the different variations of which product they have, which color of shirt are they buying? Where are they from? Are they a return shopper? What's the email address? The permutations on what can be expressed in a discount code are infinite. Shopify said, great, let's use this complete logic box, this language that gives us the expressiveness of programming and allow our customers to write code and put that code inside of the Shopify platform. And so Shopify released what they call functions, the Shopify Functions product. Which is entirely WebAssembly based.

JASON: OK.

STEVE: It's running in Shopify as a new way to extend Shopify.

JASON: So Metalx says it's great for containers. That wasn't one I considered. When I write JavaScript for a third party, something like Shopify, that can be compiled into WASM mostly just to keep the code safely boxed away from everything else?

STEVE: Correct.

JASON: I hadn't thought about that at all. That's a great use case.

STEVE: Yeah, totally. And in fact, that what Extism brings, you know, to users in terms of a value prop is really this kind out of easy mode plugin system. You don't have to make the decisions about what is the execution environment? You don't have to make the decisions about, you know, what languages are we going to allow? Usually with a plugin system, you've been limited to, oh, my app's written in Go, you can compile more Go code and I can run that Go code inside my Go code or I'm going to embed JavaScript in lieu of, and they don't have access to certain things in the host environment and Extism makes it easier to do that. I think what we can show off later on today is running these sandboxed containers of your code inside of some other code. And just kind of check out how easy that is, hopefully.

JASON: Yeah, that's really cool. I want to talk more about Extism, but there's a really good question here from gnawx. We're talking about the upsides of WASM, what are the cons? And I think the first one would be what I said earlier, which is it's pretty intimidating to start.

STEVE: Yeah.

JASON: Yeah, and honestly, is that a real con or a perception thing for me?

STEVE: No, it definitely has downsides. I mean, because WebAssembly is at the core, an instruction set architecture and a virtual machine, most of us don't work at that level day to day, right? So it's a new way of looking at how am I running code? How am I building code? So there have been layers built on top of, you know, that low level. But if you're just following, kind of the early tutorials that are still all around the web about executing WASM code, it does get intimidating fast. Because WebAssembly only has very primitive types, and so, you're dealing with float integers, that's it. You don't have strings, don't have structs, objects, anything like that. You've got to represent everything in the form of a number. And most of the examples you find, you know, kind of taking you through running WebAssembly really heavily lean into the fact that you only have numbers. You'll often find an example written in Rust or C that exports an add function. Which great, takes two numbers, returns a number. WebAssembly's really good at that. You don't have to do additional work there. You can compile the Rust code, exports the add function. You go into JavaScript, you load the WASM code, instantiate a module. And it takes two numbers, really easy. Pass the numbers, get the number back, WASM worked great. Well, now how do I pass in like JSON or some protobuff data? Or anything that, like, an application developer actually needs to operate with? That's when it gets challenging. Some of the cons are like, OK, if you want to pass a string into WASM from a host environment, because WASM explicitly operates on its own reserved, isolated memory, there's a notion of a linear memory, which is just kind of an array of bytes that's reserved for the WASM that only that WASM module itself once instantiated has access to. No other WASM module can use the linear memory given to the WASM. That's the isolation and security characteristics. But it means that string from JavaScript or from Go or wherever it's embedded in has to be copied into the WASM memory. And in order to do the copy, I have to from the guest module allocate let the host write that string into memory. And then the host has to make sure it knows, how much did I write? So I have an address in the memory and a link to that string. And then, everything is then this pointer and offset pair in order to just like use a string. And that's a very foreign concept to most developers today. And so

JASON: Yeah, I'm actively fighting.

STEVE: It's tough.

JASON: Hearing you talk about it, I'm actively fighting to keep my eyes from crossing, because it's heavy, right? Having to juggle that type of information, it's just so it's a lot of things to keep track of to know what's going on. And, you know, this is one of the reasons I don't do a lot of I ran away screaming from C++. And like my brief experience with Rust, I kept tripping over things like that where it was like I'm supposed to put something over here and I have to, like, you know, share memory and unshare memory. There were a lot of things going on. I'm sure, obviously we can learn anything if we put our minds to it. But I'm over here in my happy, free for all in JavaScript doing whatever I want and nobody cares. And it's like, ah, kind of like that.

STEVE: Yeah, absolutely. Manual memory management is introduced, it's like, oh, never mind, I'm going back to Ruby or JavaScript. And it's cozier over there, for sure. [ Laughter ] One of the other cons to WebAssembly, depending on your perspective, right, if you're writing C or C++ or Rust and it's like performance is my absolute requirement, you're going to see about 20 to 30% performance degradation when you compile that same code and run it in WASM. So there is a hit you take to run code in WASM. And that's because it's virtualized. I mean, it's not running directly on the chip, it's running inside a virtual machine. There are some runtimes, notably, WASM time zero in Rust and in Go that will take the WASM code and compile that to Native. They'll translate the WASM byte code and compile it to ARM instructions or x86. So it runs near native speed. It just depends on the environment within which you run the WASM code itself. And that's one of the other problems, there are some very nuanced inconsistencies between where do I run the WASM? And how is it going to behave? Or how do I execute it? Or which language should I use to compile to this WASM code because it might have a slightly different interface to initialize that code and set up the run time. Go has a scheduler and a garbage collector and all of this other runtime code along with your code. So that has to be compiled into the WASM, as well and instantiated.

JASON: Yeah.

STEVE: These little interesting nuances between language to language and runtime to runtime that can cause some problems sometimes. And one of the ways I like to describe Extism is it's kind of like JQuery for WASM. In the past, helped you smooth over the nuances between the browsers. We didn't have Fetch forever. It was XML HP request, it was different. It behaved differently, IE, Firefox, Chrome, and so Jquery presented this universal interface that you could program against that behind the scenes, J Query would say, you're in Firefox, we're going to do this instead of that in Chrome. Extism hides that nuance behind the scenes for you so you don't have to worry about it. If you can compile an Extism plugin, you can run it in an Extism host and you're not going to deal with the nuance complexities.

JASON: Very cool. I think this one's a quick question. How does garbage collection work in WASM modules?

STEVE: It's a quick question that could have a very long answer. [ Laughter ] There is there are two ways, right. So the first way is like I mentioned with the Go use case. Go has a runtime, it has a garbage collector, the garbage collector in Go is actually compiled into the WASM module itself and memory is reclaimed for you automatically in the WASM instructions because those WASM instructions are the GC code from Go's runtime. There's the second option. And the first option is also used in all of the other dynamic languages. If you can compile Java or JavaScript or Ruby into WASM, it's also going to have some form of its own garbage collector packed into the WASM binary. And the side effect of that is that the WASM code is large. A Go binary with a runtime in it could be a few megabytes, could be 10 megabytes, depends. The second way is a standard, which is emerging by the WC3 and the group working on WebAssembly. And it's called WASM GC. And it describes an interface for a WASM module to handle memory management without having to bring a GC along with the WASM. It can be shared amongst the WASM code that's compiled. It's going to be available. And it's enable things like better string management and better reference handling, and will make languages like Java easier to compile to WASM when there's a garbage collector involved.

JASON: Definitely.

STEVE: More ideal.

JASON: Excellent, all right. So I have 9 million more questions, but I think it'll be easier to look at them than to try to talk about in the abstract. So let me switch us over into the paired programming view. And, first and foremost, let me drop a quick link to your Twitter for everyone. So for anybody who wants to followup with Steve, you can find him right the heck did no not that. Get that out of there. You know, it does this thing where, it's like, I'm going to copy a link. Just kidding, I'm going to copy a different link. This is the one. This is the one that we want everyone to look at.

STEVE: Hey.

JASON: And then, we are talking today about Extism and also just about WebAssembly, right? So WebAssembly itself has a whole website that you can go and look at if you want to dig into the underlying bits, and then, Extism, I don't think I actually asked you for a high level, what is Extism, we just sort of started talking about it. What's your elevator you said JQuery for WASM.

STEVE: Yeah.

JASON: Let me see if I can elevator pitch it. J Query for WASM, meaning, I can take something I want to convert to WASM and instead of having to learn the specifics of compiling the C++ to a WASM module and the specifics of loading a WASM module into the environment that I want to load it in, say Go or JavaScript or whatever. I would, instead, use Extism to compile any on the screen into WASM and I can use Extism to load a WASM module into any of the host environments you support. Is that correct?

STEVE: Correct. Absolutely. I'm going to write that down and use that from here on out.

JASON: Great. OK. No, that's great. And I came in with very little knowledge here. So I think just through, you know, the way we've been describing this through inference, it was very clear that was the goal of Extism. Super excited to give this a try. If I wanted to do that, what's our first step? I wanted to write some code.

STEVE: Yeah, Extism.org, which you have up here is definitely a great place to start. It's going to hopefully lead you down the path of figuring out, OK, what language are you working in right now that you want to run WASM in. What language are you compiling in WASM and want to run in an environment that can execute WebAssembly. Here's the list of languages we support with our official SDKs, which describes the interface from a host environment, embed WASM code in my app. You're going to use an SDK. And we support like 16 different languages. And, it's really the easiest way to load WebAssembly code into your application. You don't have to make the choice of code which runtime do I need to pick and how do I write the right FFI bindings? Or is there a runtime that's in my native language that I don't have to use FFI? So, for example, in Rust, in Go, in JavaScript, there are native runtimes available that we've handpicked and wrapped for you giving you a nice layer of abstraction so you don't have to deal with the intricacies and nuances that I mentioned. And then, on the other hand, in languages like Ruby or PHP, Python, Java, Zig, et cetera, there isn't the native WebAssembly runtime, so we have kind of gone through the toil of writing the wrappers around FFI interface for you so that you can actually load the code inside those languages and run it very easily without having to know, OK, I've got to talk to this shared library across CFFFI and execute WASM code, it's a nice library you can install and just get to work. That would be the first question. Which language are you using? And do you want to run WebAssembly code inside of it?

JASON: I think the most practical use case for me would be sandboxing JavaScript inside of JavaScript.

STEVE: OK.

JASON: That's probably like the first thing that I can immediately see myself doing is trying to build a plugin system for an app that I maintain, I'm a JavaScript dev most of the time. So that's probably the workflow that would be the first one I'd get stoked about.

STEVE: Cool. Yeah, we could definitely do that. I think it would be fun to do like a combination of, you know, we have a JavaScript host application, sure, we can compile JavaScript, we can compile some Go and run those inside the JS. But now that we have those plugins built, we can also switch gears and go into a PHP app or something.

JASON: Absolutely.

STEVE: And run the same plugins without any modification and execute the same plugins there.

JASON: You're saying I've got a scenario here. I've built a SaaS app and I build that SaaS app to have, you know, it's multitenet. They compile into WASM modules and I run them inside of my node, my node SaaS app. Later, I decide we're going to migrate. We rebuild it into Go or Rust or something. And you're saying that all of my user extensions don't have to change, I can just pick them up and run them as the compiled WASM modules they are?

Absolutely correct.

JASON: That's pretty sick.

STEVE: Thank you. One of the other interesting things about Extism is, to my knowledge, it's the first off the shelf universal plugin system that's portable across any language we can embed it in. The exact same code you could deploy to your JavaScript app will work in somebody else's Ruby app or somebody else's PHP app. And so this kind of cross pollination of plugins mean if you're a plugin author and you want to write cool code that's going to live inside this, you know, whatever, WordPress application, that same plugin could be used in a CMS that's run in a completely different language. You increase the developer audience of who can use these plugins, as long as there's an Extism host running inside of that application, of course.

JASON: Got it. Got it. That's extremely cool. OK. So I think I get it in the abstract. And I'm ready to do it for real.

OK. So let's see, we've got about an hour. And I'd love to do both. Let's build a JavaScript version and a PHP version. We might have to go a little contrived on the actual examples we're doing.

STEVE: Yeah, let's start with our readmes, they go through how to quick start a JavaScript app, for example, to run WASM code.

JASON: OK.

STEVE: Go to the JS SDK through any of the JS links there. In the read.me, there's the how to get started with this, install the Extism NPM module, by the way, JS SDK works in every JavaScript environment, whether you're on Node or Cloudflare workers, any browser, same library.

JASON: OK.

STEVE: Which is pretty cool.

JASON: I'm just going to throw in a quick Node package, I'm going to get in it so it doesn't hide all of the file names. And then, I'm going to install Extism.

STEVE: Sorry, I think you have to prefix dollar sign.

JASON: Got it.

STEVE: And then, in the read.me, it'll show you the boilerplate, you're going to create some file and import

JASON: Yeah, let's do it as ES module. Why not, right? We're going to go into package JSON and make this a type module. And oops call this index.js, probably because I'm not going to set that up right now. All right. I've got my create plugin.

STEVE: We have this demo WASM module we like to use, which does the incredibly challenging job of counting vowels in a string provided to it. And the reason why we use this demo, not only does it test a number of the things we have to build into the runtime, but the Extism runtime, but also shows that passing complex datatypes beyond the numbers that WebAssembly by default supports is really, really easy. So I would just copy that straight up. You can use a URL, which this showcases as the source of the WASM code. You could, of course, load it from disk if you have, you know, your code locally, you could have a byte array of WASM code, as well. Same interface. So this going to work fine.

JASON: So this is slick, though, because you're saying I don't need is there any performance indication of using URL versus having it downloaded locally or anything like that?

STEVE: Yeah, just outside of Extism, that would just be, is it faster to load something off the network? Or is it faster to load it off the disk? If you have the code locally on the disk, it's going to be faster to load it off an SSD from your machine than the network, this makes it easier, you don't have to download anything. I will ask you to download some code so we can show off kind of what's actually in this WASM code that we're looking at.

JASON: Yeah.

STEVE: Let's get through this kind of bootstrap tutorial, first, and get into the nitty gritty.

JASON: OK. And let's see, we've got pretty straightforward call here. We're going to get our output by awaiting plugin.call. That's nice. And I assume this is the name of the function that gets exported. And then, input, and our input can be looked like there was a format for this, probably.

STEVE: It's just any string. You can pass in, hi, my name is Jason.

JASON: Oh, it's just the got it. The string we're counting the vowels of. That makes sense.

STEVE: Yep. Exactly.

JASON: So, let's see, the answer should be three.

STEVE: Fingers crossed. If our math

JASON: Let's run this. Look at it go.

STEVE: So, yeah, we can step through what actually happened here. So there were some things going on behind the scenes. Namely, when you create the plugin, there's this configuration plugin you can pass. And use wasi is one of the options here. Web assembly standard interface depending on who you're talking to. And basically describes ways of giving WASM this remember an overengineered calculator, additional capabilities. And in this case, the code doesn't need WASI, because it's reading the input from the host, running through a string counter and checking if a value in the string is a vowel, or not, and then returning back some JSON. But if I wanted to go and make a fetch call, if I wanted to do anything with the systems resources, I would need WASI. Just to call out there, there are other configurations in the docs, but for all of the codes today, we shouldn't need to do any additional configuration.

JASON: I think a thing worth calling out here is we sort of we mentioned it, but I want to focus on it is that you were talking about the fact that in a WASM module, all we get are numbers by default. And so, the fact that we got JSON out, that we had our string going in and we didn't have to I didn't have to actually allocate linear memory, which as you were talking about that, I was kind of going, no, I'm in for a rough episode. [ Laughter ] Right? The fact that I did this like I would any old JavaScript function and this abstraction handled any of those things for me

STEVE: Yep.

JASON: that's slick. That makes me feel like I could use WASM in a way that doesn't make me want to like run away screaming from the challenge.

STEVE: I love to hear that. Thank you so much. Because I think that the biggest drawback and barrier to entry with WASM is exactly that. I'm not going to define and allocate function in my guest code and call the host to give me some memory and then deallocate that memory or reallocate that memory. It's just too much just to run what I want to do, which is use some code from that language in my app, which is written in a different language in a secure and high performance way.

JASON: Mm hmm.

STEVE: So I appreciate that. And you're 100% right. A lot that happened, you pass in the string, goes somewhere in the memory, the guest code needs to figure out where it is and load it into the Extism. And we'll show some Extism code in a minute. Writing an Extism plugin is little different than defining a function, getting its arguments, using the arguments and the function and then returning a result. You're actually dealing with input and output. And so, like the plugin gets input, which is conveniently named input in the interface here, and it returns some output. And so, we'll see this when we do a little demo of writing a plugin, too. And the output itself also has some nice type features, as well, out.text, UTF8 string, out.json will give you the opportunity to kind of like cast that JSON into whatever your nice type is. And then, there's out.array buffer if you want to use it in, like, let's return an image. Maybe the plugin is the filter or something like that I've applied and it gets to run high performance or Rust or C code to the image manipulation. And I want to use the blob or the array buffer directly outside of JavaScript. So

JASON: Very, very cool. OK. So are we done? That's it, right?

STEVE: That's it. We set up a JavaScript host environment. Hands clean. We did it. [ Laughter ] We can go a couple different ways. We can go and write a new plugin. And run it inside this, or we could basically do the equivalent in PHP and just kind of get that set up so we're ready to go and plop a new plugin into a different environment. How do you want to go?

JASON: Let's do that. I installed PHP on this machine 30 minutes ago. So I haven't written PHP in ten years. Let's go.

STEVE: Oh, boy. All right. Same thing is true. Instead of the JS SDK, you can do the PHP SDK.

JASON: There it is.

STEVE: The logo will get you there, too. And there's one kind of additional step here. One additional where Extism defines this abstraction of which runtime is going to execute the Extism code for you, PHP doesn't have a native runtime, JavaScript does, it has the browser WASM engine from V8 or JSC or wherever, and defines the APIs that are usable from JavaScript into the environment. PHP is not the same. It does not have a native PHP runtime, but it is bolted on to the PHP runtime. We have to bring one in for you. That's where the CLI comes in. We have to install the Extism CLI first, which will make it easy to install the Extism engine which gets run for you when you load the PHP SDK.

JASON: Got it. And I don't need to modify is there anything I need to do to PHP itself?

STEVE: Most PHPs don't enable FFI out of the gates. So we have to enable that in the the init configuration. There's a one liner on the Extism/CLI repo. Look at you reading docs. People read docs, they get things done. [ Laughter ]

JASON: Let's see, this looks like it'll work. I'm going to do that. Proceed. Let's see if I can do this on the first try. Hey, second try.

STEVE: The pressure of entering your password on stream is real.

JASON: Let's see, and then I need to go back to here. And we'll try this one, again. All right.

STEVE: Those aren't familiar with a shared library. If you've used something like SQLite, you're talking to a shared library that's written in C installed on to your system and accessing that database is done over the CFFI, the foreign function interface. Extism is no different when you're running from a language that doesn't have a runtime like Go, Rust, or JavaScript. And so, we have to kind of bring it along for you. This step is installing Extism on a system that needs it.

JASON: Just realizing I don't have any of the PHP ecosystem. So hold, please, while I add Composer. [ Laughter ]

STEVE: The blissful ignorance of not having Composer.

JASON: It was definitely nice for a little while. [ Laughter ] to just have only like JavaScript. But over time, I think over the last few weeks, I have installed Python, Go, PHP, still haven't installed Java. We're it's all over the place. This computer's ready for a computer science degree at this point. [ Laughter ]

STEVE: Give it an honorary degree. [ Laughter ]

JASON: All right. So, we're ready, I think, now. So I can go back here and then I'm going to run this one. Composer not found. Wait, what do I have to do? PHP composer. Oh, do I have to do it like that?

STEVE: I think it depends on how you install it.

JASON: That's fine. We'll do one of these because

STEVE: Progress is progress.

JASON: It's very unlikely I'll use PHP much beyond today. But now I have Extism installed in my PHP project.

STEVE: Right on.

JASON: OK. I can move on. Next step.

STEVE: I think.

JASON: Do I need that? Or is that working?

STEVE: I'm not sure. Try it without it and

JASON: OK. So then, we're going to get into our index.php here, and that's living right there. So we're going to get the Extism plugin, the Extism manifest and the URL WASM source, which is because we're going to use the URL like we did in Node?

STEVE: Yep.

JASON: OK. And then, we get to do stuff. So

STEVE: Takes you through the steps of JavaScript, find the source, create a plugin.

JASON: You don't prefix your variables in PHP, which will always melt my brain a little bit because the JavaScript brain is saying that's wrong.

STEVE: Oh, yeah. [ Laughter ]

JASON: So we're defining our source, and we grab this plugin count vowels.

STEVE: The exact WASM we used for the JavaScript example. We're busy counting vowels.

JASON: OK and the manifest, is that a PHP thing?

STEVE: This is an Extism thing, this defines the blueprint of the module, the source of the link of the WASM comes from also restrictions about the runtime. So we didn't talk about the additional security and constraint that apply to WASM. So Extism provides a bunch of ways to say, I only want to allow my module to run for X amount of time, I don't want to eat too many resources. I want to reach out to these networks, declared by host name, and I only want to access to files on disk. So it thinks it's in ETC/password, but it's actually just in a file called, you know, fake.txt.

JASON: Yeah.

STEVE: It's about control and security, the manifest.

JASON: Got it. This is sort of the same thing that the create plugin call is doing in Node?

STEVE: Exactly. Instead of a URL, you can pass in a manifest to define the plugin in a more sophisticated manner. But for demos, manifest works great.

JASON: We've got the URL, set up the manifest, we define the plugin with the manifest and true

STEVE: This is the WASI setting. If you want to plugin WASI capabilities, pass in true. It's OK to leave it if you don't use it, nothing's going to happen.

JASON: All right. And now we've got one of these so that we can call our plugin, and obviously, we're going to greet the chat. So hello, chat. And then, this looks familiar. We're doing plugin calls so the JavaScript equivalent of plugin.call. Count vowels. And then the input.

STEVE: Right.

JASON: And I want to print this. How do you print?

I think you can just echo it out. You can do echo

JASON: Echo, that's right.

STEVE: .output.

JASON: It's so long since I've written PHP, I was like, where is the dollar symbol? Did you just run PHP?

STEVE: The one caveat, we may have to enable FFI. You can try it and it might fail.

JASON: Let's see what happens. Oh, no, I did something.

STEVE: Yeah, we need our fun PHP open bracket. Which is not in the very beginning of the file, we need a

JASON: That's right. Oh, so many memories just flooded back. Holy crap. So then, we're going to run this and it says WASM source.

STEVE: Scroll up.

JASON: Not found.

STEVE: We may actually run this with Composer, can you go back to the read.me and check if there is ?

JASON: That's a good point. It probably needs to be run with Composer.

STEVE: It should say something, maybe not. Here's the downside of people who aren't active PHP developers demonstrating PHP code. It should work. If you go back up to the repo in the GitHub actions folder, you can see an example of this code executing.

JASON: Example.

STEVE: Maybe there. But it would be in the GitHub actions, .github directory.

JASON: Oh, here?

STEVE: Yeah. And workflows. YAML. There should be a test.

JASON: PHP test. In the make file, which is here. PHP vendor. Tests. Composer install. Runs test.

STEVE: Then it does oh, it just runs the tests.

JASON: OK. OK. We can do this. [ Laughter ]

STEVE: We'll focus on JavaScript. I'll get some help from the person on our team who does the PHP, and then see if they can figure out what's going on.

JASON: OK. The problem here, to be clear, is that we don't know how PHP works, not that. [ Laughter ] Not that this isn't working. [ Laughter ]

STEVE: Yeah. I should have I should have been more involved writing the PHP SDK, unfortunately, I was not. Or fortunately.

JASON: Yeah, depending on how you look at it, I guess. Is there it doesn't just say how to do stuff. So yeah, all right. Back to JavaScript for now.

STEVE: Fun JavaScript. So we're going to write a plugin, though, right?

JASON: Yeah.

STEVE: Think about the other side of the coin, how do we write our own plugin? And I think one thing that is useful to look the a here is actually to download that count vowels plugin, and we're going to open it up in a new tool to take kind of an analysis of WASM code.

JASON: I did just realize that your logo was like a metal band poster.

STEVE: Yeah. [ Laughter ]

JASON: Which is wonderful.

STEVE: Yeah, the reason for it is like running untrusted, arbitrary code inside your application was like not a safe thing to do. Nobody would do it. This is a little bit like a hat tip. What used to be crazy is now not. And it also kind of looks bad ass. So. [ Laughter ]

JASON: I love it. I love it. So you told me what to do and I wasn't listening because I was looking at your logo.

STEVE: Good point. The logo is cool. I appreciate it. Back into the JavaScript app. If you copy the URL that is loading the WASM. Whatever you've got installed to pull that down.

JASON: Do I have W Git? Let's find out. We're going to do curl. What did I just put that into? Is this going to work? It would be really cool if I got that right on the first try. Nope. [ Laughter ]

STEVE: You can just pass it dash O staff of recounting. You can do dash o. Lowercase o.

JASON: Do I need to name the file?

STEVE: It'll write the file there. It's weird, though, it doesn't look like you're actually downloading anything. If you look at the output there.

JASON: Yeah, so

STEVE: You can pop it into the browser.

JASON: Plan B is do it the hard way because I don't remember how curl works.

STEVE: I think you did it right. I sent you a link in the private chat to a tool called modsurfer, a static analysis tool for debugging and insights in your WASM.

JASON: Got it.

STEVE: Open up a browser and go to that link.

JASON: Let me drop a link to this in the chat, as well. OK. So now I have a WASM file. I'm going to drop it into the drop box spot.

STEVE: Nice. And so this did a big scan of that code. It opened up the WASM binary. It iterates through all of the components inside the WASM, all the imports and exports, does complexity analysis on the code for you. And that code it actually generates on the right hand column should look fairly familiar. And in fact, you can run that just in your browser if you open up the console, it'll just work. The point of this exercise, though, is to go down and look at the exports of the table. You look the a the imports, first, these are interesting to see, a bunch of functions that the host environment gives you to handle that memory management. Allocating, deallocating and storing input and output. We have a whole variable system if you want to use variables inside your plugins that are persistent across function calls. The exports define what are the functions that a host can call on a WASM module? So in this case, that's the count vowels function you used to say, hey, when you get to the module, find this export and execute it and pass the data in and then expect it to return some data in the output. So this is a handy tool to look at what's actually in my WASM and what functions can I call that this thing exports to me? So we'll use this, again, after we write our own module and verify it's actually there and we can call it the right way.

JASON: Got it. And we can see this was written in Rust, which is also kind of cool because we just ran Rust in the browser and I didn't even know.

STEVE: That's right. Exactly. So, let's switch, and I have a little Go example that we could just use and I can kind of talk through it. Up to you if you want to write something from scratch. We have to come up with a new idea, I have a pretty canned one, I think it's kind of fun.

JASON: Yeah, if you've got a canned one, let's roll.

STEVE: I think we're coming up on time.

JASON: Yeah, we've got about 30 minutes before we have to start winding down.

STEVE: Perfect, I think we can get this done no problem. I can give you some code. I think it's going to lose its formatting in our chat, but that might be OK.

JASON: I've got autoformat, it's going to be great.

STEVE: OK. If it doesn't work, I can plop it in and share you the link. Yeah, it totally

JASON: Just madness, but it's totally P fine. What kind of code is this?

STEVE: This is going to be some Go code.

JASON: OK.

STEVE: And we're going to use the Go PDK. The other side of Extism is the PDKs. We talked about the SDKs where you load a plugin, run plugin.call, which allows you to run WebAssembly code in a variety of languages.

JASON: What did Jason do wrong here?

STEVE: Yeah, it lost its formatting. If you have Go installed, you can run Go fmt on this file. I bet it doesn't have format on save. I think it's going to install and set it up for you. Yeah, there you go.

JASON: It told me to do it and then, I did. Let's see format?

STEVE: It may if you click the extension that you installed and go to its extension page

JASON: Oops. Extensions.

STEVE: Like, on the right hand side where you have the extension marketplace. Yeah, and install it and reinstall it, and that little question to prompt you will prompt you, again, to see if you want to install tools for Go. We have to open the Go file, again.

JASON: So that was a suggestion to install this module?

STEVE: No, there are other tools that Go extension wants to install for you.

JASON: Ah, OK. Let me reload. And then, I've got my index.go, install it one more time.

STEVE: It says all tools successfully installed. Let's go back to this. And if you save it, it should just format the file.

JASON: It does not like something I did here. And I have no idea how Go works, so I'm unable to help.

STEVE: All right. Go into your terminal and see if you have a command in the Go tool called Go space fmt. OK. So you do have one.

JASON: Do I need to

STEVE: Also need to run go to a module system like NPM.

JASON: I think it might have tried to format to something else. Let me because it's like it's telling me there's a syntax error.

STEVE: Yeah, there shouldn't be a syntax error. I'm going to copy this for you and change the formatting.

JASON: And then we'll find out that I have the wrong version of Go or something.

STEVE: You'll need to run go mod in it. And give it a path. It could be JSON

JASON: OK. And then we have, let's see, so I'm looking for... scanning the chat.

STEVE: Now you want to install Go modules, Go Get and GitHub.com/Extism/go pdk. And actually

JASON: Cool.

STEVE: It should be done because the other one is just part of the standard library.

JASON: OK. Grabbing this. Yeah, I'm grabbing it now.

STEVE: Cool.

JASON: Stop yelling at me. I've done nothing to you. OK. But we're OK now, right?

STEVE: I think so if you do LS terminal, you should have main.go and go.mod. Yeah.

JASON: OK, and I called this index.go, do I need

STEVE: No, it can be called index.go.

JASON: OK, I wanted to see how many index files we could get up to by the end of this.

STEVE: A bunch. Let's walk through this code a little bit. It's going to talk about other things about Extism that are useful that are part of that abstraction layer I mentioned. Scroll up to the top of the file here. The first thing you'll notice is declaring this type. The Go standard library defines, really, I think it's a helpful way of formatting times. If you have a time in some other format or just nanoseconds or whatever, Go has this library in standard library, the time package that makes it easy to reformat a time into some like more human, readable string that's just kind of easier to use. And it's a pretty nifty little thing and unique to go, but one of the cool things about Extism, we can share code across languages. I can repackage that library from Go and use it inside of JavaScript. And so, what this JSON time struct does, says this is going to be the input of the plugin. I'm going to take a time, which is written in JavaScript and a format, which describes the way I want to reformat that time and print it back out from the plugin so that's going to be our input we're going to pass the plugin. And then, we define this function called format. And notice, there's this magic comment above it. This is a Go thing. This is how Go says, export this function to the environment as a symbol for something else to execute when it wants to call my shared code. So, by adding this line up here, when we compile the Go code, there'll be a function in the export table called format. And

JASON: Got it.

STEVE: All Extism plugins share the same signature. Take no arguments and return a 32 bit int which is a number that acts as an error code. You probably used command line arguments in the past. Gives me a one or negative 2 or whatever. That is an error code that says, hey, it was a nonzero exit code, this failed. Extism gives you the same kind of escape hatch to describe an error. In Go, you can unmarshal JSON into a type. Here's the type, I'm going to declare a variable called T, and it's of the type JSON time, which we looked at as instructed above. And then we have a PDK helper function from Extism's Go PDK that says, I want to get JSON input from the host and load it inside my plugin. This abstracts all of that memory management stuff you have to do otherwise. It also says, give me the variable you want me to deserialize that JSON into for you automatically. This is going to take the T, JSON time, convert the input into the JSON struct for us. We have error management next.

JASON: OK.

STEVE: Which is probably familiar to Go programmers. But in this case, we're going to tell the PDK, hey, we have an error, I want you to be able to tell the host environment exactly what that error is and kind of bubble it up to the host country run to say this is

JASON: Nonsuccessful error code.

STEVE: So that is pretty straightforward. The actual code is now taking the Go format function which is in the standard library. And formatting the string to whatever the specification that the user calling the plugin wants to reformat it to. We'll do a demo in the CLI and inside the JavaScript, too.

JASON: OK.

STEVE: What we've done here, though, is also important to look at there's this output string function. This also says take the string from whatever I'm using in the Go code and pass it back to the host as the functions output it's not a return, value, though, because we don't return the data from the function, we return an error code.

JASON: Right, we return like nothing went wrong.

STEVE: Exactly. Exactly. Because the function in WASM can't return a string, it can only return a number. So we are actually instead of writing that string to memory in the host, and then the host knows where to find that output because we've used this helper function.

JASON: Got it. And this is the stuff that, like this is why Extism is valuable because if we didn't have that, I would be responsible for writing it into some memory, and then, I would need to know how that goes across boundaries to extract it later.

STEVE: Exactly.

JASON: So this is sort of I feel like the side by side of how you would bo this without Extism is probably the selling point. Even hearing you explain what it would take to do the memory allocation and stuff, I'm just kind of like, like I can feel my eye twitch.

STEVE: It can be pretty tough. It can be pretty tough. In fact, we have a really good blog post about exactly that. Kind of the side by side. What is raw WASM passing complex data compared to Extism, and I shared it in the private chat.

JASON: Yeah.

STEVE: If folks are interested to see what you would have to do on your own to write complex data into memory and read it back from the guest and pass it back and forth to the host and all of that stuff. It's doable, for sure. But it's a lot of code that you probably don't want to write if you're just trying to unload WASM and run it.

JASON: Please, no.

STEVE: So there's one other thing that we should mention when it comes to compiling Go code in particular. You can certainly use the standard Go tool chain. But like I mentioned earlier in the call about Go is runtime adding a bunch of size to the WebAssembly module, there's an alternative compiler called Tiny Go, which is designed to take Go code and run it on microcontrollers, tiny devices. But they have a really they have really great WASM support, too. We recommend using tiny Go when compiling plugins. Over the time the Go standard toolchain will certainly improve in terms of the ability to compile smaller WASM binaries. But for now, Tiny Go does a better job. And so, I think we talked about installing TinyGo.

JASON: Yeah, I have it. If I spell it right, I have it.

STEVE: There we go. So tinygo has a build command and you pass that dash o to tell it where to output the binary. Format.wasm. And then, you have to give it a target because target WASI.

JASON: Is that dash T?

STEVE: Dash target, and space WASI. And we're going to do index.go, which is a file to build.

JASON: OK, tinygo build, our target is wasi and the file inputting is index.go, right?

STEVE: That's right.

JASON: Here we go. Uh oh. Inconsistent vendoring. That's probably my fault.

STEVE: Yeah, let's see. We are in Extism WASM demo right now.

JASON: In Extism WASM demo and I think I name spaced it as Go PDK is explicitly required in mod, but not in modules.text.

STEVE: This is a new one. I've never seen this error before. Can you open up your go.mod. It should say require and then the path to yeah. That's fine. It also says you could run go mod vendor, and it might download the dependency into your

JASON: Yeah. I'm also wondering, did it fail or just warn? It failed because we don't have OK. So let's do go mod vendor. And it did a thing.

STEVE: OK.

JASON: Try, again.

STEVE: OK. It's taking a little longer, that's good. It's a good sign.

JASON: Oh, I wonder if it was it said it was out of sync with something in here. Maybe it just needed to have a talk. OK. So now we've got that.

STEVE: OK.

JASON: I will reveal in finder.

STEVE: Yeah, open this in modsurfer, too, it'll be interesting to see what we wrote in the module and there's more to it.

JASON: That's being loaded. We've got our imports and the allocation.

STEVE: Some host functions. And this is where it gets kind of interesting. So we do see our format function right there kind of towards the bottom, that's great. That's the export we want to call. But there's all of these other things involved here, too, which are kind of unique to Go. And in order to get like Go's concurrency and run time and scheduler and all of that other stuff, there's all these other functions put in here, and Extism takes care of calling these things when it detects it. If you try to run this code without Extism, it would be challenging. You would have to know exactly what the code is and where it came from in order to set up the runtime and allocate the structures and things like that. Extism takes care of those things for you, all you care about is calling the format function. And let me actually bring up some input we can use to test this thing. I'm going to send you a little JSON to use.

JASON: OK.

STEVE: We're going to test this in the Extism CLI.

JASON: All righty. OK. So I have copied some JSON and then, I'm going to go back over here, and then, I have Extism

STEVE: Now, we're going to use the call command. We're going to path out format that WASM. And the function inside of it which is called format. And then, we do a dash dash wasi to say the Extism CLI is going to give this plugin WASI capabilities and we're going to use dash, dash input to pass in the JSON string I gave you. And what this should do is print that timestamp, which is February 29th, 2024 in the format of January 2nd at 3:04 PM Mountain Standard Time. And this is a Go thing, where the Go library comes into play. They define this heuristic, if we find anything in the form of January with a number for the day, for the time being 3, do you care about seconds? At Mountain Standard, negative 6GMT offset. It's easier to remember, January is month 1, the second, 304, 05, and the offset is a Go standard library thing that's unique. But we're going to see this is work where it's going to reformat our JavaScript JSON time as you see as the time key. Sure enough, we get it back, printed correctly as February 29th at 6:10 AM UTC, which is not terribly belong ago.

JASON: That's pretty cool.

STEVE: Thanks. So if we want, we can actually change this code up that you wrote in the index.js. And one of the kind of convenient things about using modsurfer about introspection on your code, we host that code for you. If you want to use that and replace the GitHub

JASON: Let's run them both. Let's do all sorts of stuff. So I'm going to I'm going to try to write this from on my own. And can I just do something like this?

STEVE: You can't just pass a file in there. You could create a manifest that has a file to it. You have to actually open the file. In this case, it's easier to go to modsurfer and there's a button that says copy WASM URL. And you can use that.

JASON: Oh, here. OK.

STEVE: There we go.

JASON: And I wanted it to be get out of the way, helpful hints. Use wasi is true. I'm typing like butt today. OK. So then, let's see, we'll call this date plugin. And then, up here, I'm going to have format will be so it's just January so can I do like a different format? January?

STEVE: You want to use basically the exact same JSON string I sent you called in the Extism plugin.

JASON: Right. I still have that in my clipboard here. I've got one of these. And you're saying in the Go standard library, I can just sort of mess with this however I want?

STEVE: Yeah, as long as it follows the convention of, one, being January, two, being the date, three, being the hour, four being the minute, five being the seconds, PM and then MST, you don't have to have all of those components. It's just going to looker for those things and parse it correctly using the data it can recognize as input and reformatting it based on the format you specify.

JASON: I'm just going to change this up a tad.

STEVE: Sure.

JASON: And then, I should be able to say let's see output. It's going to equal await plugin.call. No format plugin, date plugin. .call. And we're calling format, which is the function we wrote. And I'm going to I shouldn't have called this format.

STEVE: Naming's hard.

JASON: Yeah, that's uh whatever, this is fine. And then, I will console.log my output.text. And if I've done this correctly, we should see our vowel count, and then, we should see our formatted date.

STEVE: Yes.

JASON: I'm going to run... node. And off we go. We've got our count. And then, we've got our format. And it did follow my like shortened format.

STEVE: Yeah.

JASON: Which is very cool.

STEVE: Sweet. We did it. One more kind of fun thing to try. If you go back to Modsurfer and copy the code snippet that's on the top right of the page

JASON: Mm hmm.

STEVE: Just to show the code running in one more place. Why not? If we copy that. Drop it in and then, the only thing is when we're going to use a different format to use that same, sorry, different input, use the same JSON string.

JASON: Yeah, you're right. I should have no, stop. This

STEVE: That should do it. There we go.

JASON: Look at it go.

STEVE: We've moved a bunch of code around a bunch of different cool places. I think it's a lot of fun.

JASON: And this is executing safely. Like

STEVE: Fully isolated from the JavaScript host, from your browser, it's running in its own little sandbox inside of the VM that your browser's running. Running the WebAssembly VM, which is inside the V8 engine inside the Chrome browser and it has no additional capabilities or access. Can't read any secrets or local storage in your browser. Can't do anything to bury us. Just running the code you tell it to run and that's it.

JASON: That's pretty slick. And if we could figure out how PHP worked, it would work there, too. [ Laughter ] .

STEVE: Yeah, I'm disappointed, that one should've worked. I apologize for that.

JASON: We have a minute. How to run PHP with Composer. Is there like a how to run PHP code using Composer. I don't like whatever that is.

STEVE: I'm pretty sure PHP index.php should've worked.

JASON: I want you to do the thing, though. Ready to use it, whatever. It's fine. [ Laughter ]

STEVE: It's complaining because it can't find the Extism library, but you definitely installed it with Composer. Yeah, I kind of feel like Composer should have.

JASON: I'm wondering if because I don't have Composer aliased?

STEVE: It should work, still. The way you've installed it, it should still work.

JASON: And composer doesn't, like does it run things? Basic usage. We know how to require things.

STEVE: You have Go running. You could use, you know, the Go host run it in Go instead of PHP.

JASON: Yeah, you know Go, I don't know Go, but let's do it. Let's try to get these running inside of Go.

STEVE: You'll have to create a new directory, you already have a Go module we could reuse this. You've got to install

JASON: I could make a new folder, right?

STEVE: We have the technology, right? [ Laughter ]

JASON: I've got so much memory on this thing. All right. So 7 minutes, countdown starting now, we're going to

STEVE: We've got 7 minutes.

JASON: We're going inside here, and I'm going to go into that folder and I needed to what was it? Go

STEVE: Go mod init. And then, it was give it one of these.

STEVE: Love it. And you're going to do a go mod sorry, go get, and GitHub.com/Extism/go/sdk.

JASON: Extism/go/sdk.

STEVE: Yep. And if you go to that URL, you'll see an equivalent kind of quick start to load the boilerplate, load a plugin, execute a function in it.

JASON: Extism, go SDK. And let's see, we already did that. So then, here we've got our plugin code.

STEVE: Yep, do a main.go or index.go.

JASON: Main.go, that's the convention. So here we go, inside here, we've got our package, we're importing some things, we've got our manifest

STEVE: It is a little more in depth about the manifest, describes the blueprint of the plugin of the code you want to run. One thing we didn't talk about the host functions Extism. If you want to link functions from Go and pass the functions into the WASM, you could do that using the manifest and add host functions which let the WASM code do more. It can very deeply integrate into the Go code that the host is providing. So if you wanted to let your WASM code issue a SQL query through your Go application, you could do it. So, yeah, we have our plugin, which I think the problem is, we're just not using it at this point in time.

JASON: Yes. We're missing pieces. So now, we're going to call our code inside of main. So down at the bottom, I assume. So we've got our actual thing. All right, which we are obviously going to update to be hello, chat. And we call the plugin and update the errors, update the string. This is making sense. I'm following. And then, to run this I do go

STEVE: Go run, main.go.

JASON: Main.go, easy peasy. And there it goes. All right, so now, I have my other plugin, and so, let's see if I can figure this out.

STEVE: Let's do it.

JASON: It would be manifest 2, that's a fun symbol, then Extism.manifest, and oh, no round boys for the that's chaos. It's chaos. I can do this. [ Laughter ] So I've got my extism.wasm, and the one we copied from here, the Modsurfer, that's the one we wrote. Why are you mad?

STEVE: Needs a comma.

JASON: Needs a comma, OK. And you need a comma. All right. And so then down here, we'll set up plugin 2 and error 2, and those will be the output of Extism.new plugin, and can I use the same context?

STEVE: You can use the same context, you want to remove the extra parentheses, though.

JASON: Yeah, doubled up there. Context manifest 2, and what was this thing? Config?

STEVE: You can reuse the config and pass in the nifty host functions.

JASON: Is that what your username is?

STEVE: That's where it comes from.

JASON: Got it. OK. All right. And down here, I'm just going to copy/paste this part because I don't really care.

STEVE: Yep.

JASON: OK. And then, down here, we're going to is it OK to

STEVE: Yeah, yeah, it's not going to return, you can just yeah, exactly.

JASON: OK, and it's a byte, again?

STEVE: Yeah, the input 2LX plugin is an array of bytes. You can build abstractions on top of it. If you want to pass numbers and strings and structs as long as you can get to bytes when you call the plugin, you're good.

JASON: Got it. What is the convention for a JSON string? Do I need to double quote and escape?

STEVE: Do a back tic, just like in JavaScript.

JASON: Got it. Now what are you mad about?

STEVE: Might be reassigning data you can delete the colon or data, too. That works, too.

JASON: All right. And then, I have my exits and outs. We'll do plugin 2 call. And that one's going to be format. Oh, format. OK. So this will be exit 2, out 2, error 3.

STEVE: Sure.

JASON: Sure. [ Laughter ] And then, we're going to do a check here, and this is error 3. And that would also be error 3 and this would be exit 2. And then, finally we response string out 2.

STEVE: Response 2, just so we're being conventional here.

JASON: Right. Right. Can't have this kind of chaos going on here. Format, print line.

STEVE: Response 2. The only thing we need to do is change data in plugin call at line 56 to day 2.

JASON: That's right. You are correct. OK. So theoretically, we get exactly the same output now in Go as we would have, as we did in JavaScript, both in Node and in the browser.

STEVE: Exactly.

JASON: Now we run. Fail to initialize

STEVE: We need to give WASI true to the plugin config.

JASON: Let's see

STEVE: In the plugin thing above.

JASON: Plugin config here.

STEVE: This takes a parameter, enable wasi, I believe. Capital E. Yeah, true. And then, just rerun.

JASON: And off we go. And off we went. Look at that. I just wrote Go code so poorly but it worked and I ran WASM in there. So, I'm feeling like kind of shocked, honestly. [ Laughter ]

STEVE: You killed it. You did great.

JASON: This is very cool. I love this makes, this makes WASM feel like it's within reach, right? I definitely will need to spend a little more time with the docs. But I love this idea, especially taking what we just did and realizing it's very portable, meaning that if we can get something into the .wasm format, then anybody on our team could use it whether they're writing Go, Rust, PHP, Node, whatever.

STEVE: Exactly.

JASON: The other piece that's exciting is the part I never thought about before which is that you can use this to sandbox user code. If you want to write an extension system or plugin, you could have a JavaScript app and your users can write JavaScript, but you can sandbox using Extism and safely execute that code. That's a use case that never occurred to me before today that suddenly makes me very much want to get better at this. Because I have a million ideas that I've just written off because I didn't want to figure out how to sanitizer or protect code.

STEVE: 100%. It was a very challenging problem for years and years and years and thanks to WebAssembly, we kind of get this for free now. If anybody's interested in learning more or wants to kind of go deep on this, we invite you to join our Discord. I dropped the link if Jason wouldn't mind sharing that.

JASON: I absolutely will.

STEVE: And, in fact, to speak a little bit to the use case that Jason just mentioned about the plugin system and adding extensibility to your application using Extism, we will be also releasing a platform that makes all of the kind of operations of plugins and the life cycle and testing and validation and storage and retrieval of plugins easy, as well. Please head on over, we're super happy to see you there. Good at answering questions and helping to figure out stuff if you run into issues. But yeah, this was awesome. Thanks so much for having me on, Jason.

JASON: Of course. Let me drop another link to your Twitter so if folks want to follow you there. I'm going to link to I'm going to link to the Extism home page one more time. I don't have links to all of the SDKs and PDKs and all the things you need. You've already got a link to the Discord. Make sure you head over there. And make sure you check out our sponsors, NX and Netlify, and today for the last time, thank you so much to Vets Who Code made the captioning possible. We've had Diane with White Coat Captioning with us all day making this episode more accessible for everybody, which I appreciate. Click on these links, let the sponsors know that you noticed them and you heard about them from me. While you're checking out things on the site, go to the schedule because we have just an absolutely wonderful schedule coming up. I am so excited. We're going to learn about React suspense GraphQL, haven't looked at GraphQL for a while. React Suspense is something I haven't really used. We're going to do state serverless. We're going to learn about that. And we're also going to learn about the challenges of async await in JavaScript, and I had a little prelim call with Charles, this stuff is pretty impressive. So, you know, every single one of these episodes is going to be a blast, make sure you mark your calendar so you don't miss any of these. Get on the Learn with Jason Discord, you can sign up for the newsletter, add it to your calendar, make sure if this episode is helps you learn and you're enjoying it, subscribe on whatever platform you're on, preferably YouTube, you can join the channel, if you want to throw a few bucks to the cause. And share with your friends. Hit the like button. Means a lot to me, helps me continue making more of these. Steve, thank you so much for spending time with us today. Any parting words for the chat?

STEVE: Hey, use WASM, explore Extism, it's a lot of fun. Learn as many languages and use them all.

JASON: Love it. Love to hear it. With that one, we're going to call this a huge sandboxed win. Thank you so much. [ Laughter ] We will see you all next time.

Learn With Jason is made possible by our sponsors: