Learn With Jason
Learn With Jason S9.E5 Mar 19, 2026

WASM is one of those technologies that we hear about all the time, but how many of us are actually able to take advantage of it? Patrick Dubroy teaches us first steps toward becoming fluent in WebAssembly.

Jason Lengstorf and Patrick Dubroy's Headshot on a Banner

WASM is one of those technologies that we hear about all the time, but how many of us are actually able to take advantage of it? Patrick Dubroy teaches us first steps toward becoming fluent in WebAssembly.

Read 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: Welcome to Learn With Jason. Patrick, thank you so much for taking some time to hang out with us today. How are you doing?

PATRICK: I'm doing great. How are you?

JASON: I'm doing so good. So, for folks who maybe aren't familiar with you and your work, can you give us a high level background on who you are?

PATRICK: Sure. So, yeah, my name is Patrick Dubroy, I am an independent programmer and researcher. I'm the maintainer of a library called Ohm JS, which is a library, a parsing tool kit for JavaScript and TypeScript. I am also a a co author of the book "WebAssembly From the Ground Up," which is a book about how to learn Wasm by creating a very simple compiler in JavaScript.

JASON: Awesome. And I am very excited to learn how to do, I believe, a subset of exactly that today on the show. So, I'm going to go ahead and get us right into our paired programming view here. And I'll just so, here's the website for the book. This is "WebAssembly From the Ground Up," and if you want to get a discount on the book, let me put the link up on screen here. You can use the code "Jason" to get a discount on your purchase of the book. With that, I'm ready to rock. What do we want to do first? What's the first thing we should do?

PATRICK: Okay, so, I have like a little something on the site here that you can go to. Instead of to Wasmgroundup.com. Beta.Wasmgroundup.com/Jason.

JASON: Oh, cool, all right. We're already into a personalized experience. This always makes me happy. Let's make this a little bigger so we can see what's going on. All right, what are we looking at?

PATRICK: Yeah. Well, we are looking at what we call a day in the life of a WebAssembly module. So, what I wanted to show you is just, you know, what it can look like to use WebAssembly from just the simplest possible perspective, because I think a very typical way to use WebAssembly is compiling from some language like C++ or Rust, and you get this sort of big bunch of different files that need to be loaded, and this is really taking away sort of all that complexity and just showing you what the kind of most simple thing you could possibly do with Wasm is. And this is also, though, a good example of even Figma, you know, they use WebAssembly pretty heavily in their app. It's going to have the same pattern, basically. So, there's sort of a core pattern here that you will see in basically every WebAssembly app. So, WebAssembly itself, basically, you'll see these Wasm bundles. So, you see the first line there we fetch add.Wasm. If you had some C++ and you compiled it to WebAssembly, it would produce a .Wasm file for you, which is a binary encoded set of instructions that your browser or your runtime is going to is going to eventually compile down to native code for your machine.

JASON: All right. That makes sense.

PATRICK: And the next line is basically what needs, you know, this is how in the runtime you turn this bag of bytes into something useful. So, you instantiate a WebAssembly module. And that gives us back what's called the module instance, which is actually something very similar to like a module in JavaScript. So, it's just the thing

JASON: Got our yeah, we have exports here and we have functions on the exports.

PATRICK: Yeah. So, WebAssembly, ultimately, a WebAssembly module is a thing, which can export functions, can export global variables, can import functions, and can run code. And it runs in this sandboxed way, such that unless you give it any functions that can do things, it can't really do much on its own.

JASON: Okay. And that's good, because that means we can safely do all sorts of things, including, for example, executing arbitrary user code, because it only has access to what we explicitly give it access to.

PATRICK: Exactly.

JASON: So, unless we're really insecure and said, oh, this module can do anything, all this user code, obviously, you can still get into trouble with anything, but it's kind of nice knowing you, by default, it's just going to say I'm not allowed to do that, instead of saying, yeah, sure, I'll delete the mainframe.

PATRICK: I mean, yeah. It doesn't even have a way to express many kind of bad things that it could do. Doesn't know the name of your files, so it can't delete any of your files or anything like that. It's basically so, there are I think in Wasm 1.0, there are 172 different instructions, I believe. They are basically for doing math. That's, you know, the large majority of the instructions are for doing math. There are some control flow instructions for doing things like ifs and loops. And it can call into functions that you provide to it and it can read and write local variables and global variables, but beyond that, it really does not have much power on its own, except the power that you give it.

JASON: Got it, so that's good.

PATRICK: Yes, yeah. And I think what I wanted to do here is sort of take this apart piece by piece a little bit. So, you see underneath the code we have the raw bytes of add.Wasm. There's I think a little over 40 bytes here. So, basically, all this module does is there's a function that takes two parameters and adds them. To simplify this a bit, we can represent the same bytes shown in the raw bytes text field. We could represent them as a uint8 array in JavaScript. So, the first thing I'd get you to do is copy that uint 8 array and paste it into the code above. So, we pass in the response rather than the results of you can delete that line entirely.

JASON: Okay.

PATRICK: Exactly. And where you call instantiate streaming, we're going to pass that array in. So, it just gets rid of the fetch, right. So, instead of going to the server and getting some bytes, we're going to say we have the bytes already and we're going to specify them. I think you will need to change that instantiate streaming to just instantiate, because the streaming version will expect a promise, and...

JASON: Oh, right, we were doing an await. But there it goes, we're getting the same outcome, so our math still works.

PATRICK: Exactly, yeah. And then, yeah, the kind of slightly unhinged premise that we have in our book is that we begin by actually writing these bytes by hand. So, you know, these bytes in here are it has special meaning, obviously, to the runtime. There's

JASON: Patrick, I'm going to tease you a little bit here, because remember in the companion episode of web dev podcast when I was saying this feels like it's for people who are way deeper in the stack? You got us writing byte code by hand.

PATRICK: Don't worry. This is as bad as it's going to be, and it's going to get nicer from here.

JASON: Okay, okay, all right. I'm with you. Okay, so, sorry, so you start us out in the book by actually having us write these by hand. So, I see this link here that says Wasm opcodes. When we're talking about opcodes, can you maybe just demystify a bit what's happening here? Intellectually I understand the programs pile down until there's something a computer understands but a human doesn't, and I feel that's what we're looking at, sort of looking at the matrix. But each of these things has a very distinct meaning, and I guess when you're looking at this, because I assume you are, in fact, kind of C matrix.

PATRICK: A little, yeah. Yeah. This bag of bytes we have here, kind of there's two things. At the highest level we have a file format that is really just a container for, you know, for instructions. And a lot of the stuff that you see here, these are not even actual instructions. They are just the container format.

JASON: Okay.

PATRICK: So, it's not all that different from something like PNG or JPEG. It's a flexible format that lets you put your data inside it, but the format itself kind of dictates, you know, many file formats have what's called the magic number. So, the first four bytes of the file need to always be a special sequence. And, yeah, that is the magic number for Wasm modules. The first byte is always zero, and then you have the ASCII code for letters ASM.

JASON: Okay, all right, I've seen ASCII before. I'm keeping up here. This is the ASM there. Got it.

PATRICK: Exactly. Elsewhere in the module, we have a little bit of text for the function you see the text add, as well, right? You know, in the middle of the module we have a declaration. There's a function in here and we're going to export it and the exported name is add, which is why we see the text for that. It's really only actually the first four or six or so numbers in that array. So 11 is the code for end. Yeah, this is very much seeing the matrix, that's the end instruction. The 106 there is the add instruction.

JASON: Okay.

PATRICK: 32, you see 32 up here is twice, 32, followed by zero, and 32 followed by 1. That is to get the value of a local variable, and so 32 is the code for local.git. Normally, you would not want to deal with things at this level. What we can do now, you could add a if you go up to the source code and add a debugger statement, type, yeah, just debugger. And can you open the dev tools? So, we can actually look at this in a much nicer way. The bad part is over.

JASON: We're going here. I'm going to run this.

PATRICK: So, if you run, yeah, we'll hit the debugger, and you can actually step into that call to add.

JASON: Okay. Here is the step. Which one of these

PATRICK: No, to the right. Yeah, step over. And press the step into, which is the next one to the right here. And we now see a much, much nicer representation of the same things that we were looking at before.

JASON: Okay, and so this was our 32, and this is the first variable, which is variable zero. This is the other 32. This is the second variable. And we call add. Okay, so, I'm like kind of following here. I'm not going to pretend I could write this from scratch, but I'm keeping up at least. That feels good. But I also like over here we can see, you know, the value of variable 1 is zero, three, var11 four, and we can kind of see what's happening. I like this. This is much more human readable to me. I'm into it. Okay.

PATRICK: I think looking at the raw bytes, even we don't do that. But I just kind of think it's fun to see the connection of what the browser is going to interpret in the end and, you know, the higher level representation.

JASON: Right, right.

PATRICK: I want to mention this representation you're seeing here, the text format. Yeah, it's called the WebAssembly text format. The browser, the dev tools right now are disassembling this for us, which means it has just the raw bytes on disk, but it can turn it into a human readable representation.

JASON: So this isn't in the .Wasm file. This is the browser doing a reverse translation so we can read it again.

PATRICK: Yes, exactly. So, in a production pipeline, this text format, you would never be using it directly, because say your C++ code compiles down to binary WebAssembly, the binary WebAssembly gets shipped to the browser, and the browser is going to work with that, you know. We don't need the text format in any stage of the production pipeline, but as a human it's very nice to look at it. It's much, much nicer than looking at a list of numbers. And this, you know, is fairly kind of similar to what assembly language looks like on, you know, on other platforms. It's slightly higher level, but the differences are pretty subtle.

JASON: But it's for again, the things that are intimidating about this stuff when I think about it are you're compiling your stuff down, and then it gets into production and you get a weird bug. Knowing that you have the ability to put a debugger in here and see something that's not just the compiled Wasm I have enough trouble trying to read minified JavaScript. I'm not going to dive into opcodes. It's not going to work for me. So, knowing the browser is going the extra step of giving you visibility of what's happening and, okay, you got to this call, this is what values were. That's all I need to be able to debug my code. I can see, wait, that's not what it's supposed to be. Let me figure out what I did wrong and I compile it again, run it again, and I get a better outcome. So, this immediately makes me less scared of taking WebAssembly on.

PATRICK: Yeah, that's good. And it's even I mean, some people write apps in this language actually. So, you can write your app, if you, yeah, really want to, in the WebAssembly text format.

JASON: Somebody is asking is this Lispy on purpose?

PATRICK: Yeah, I mean, it's I think it was chosen because if you don't want to argue about syntax, Lisp is well, Lisp fans believe Lisp is the primordial syntax.

JASON: Right, good. All right. I'm into it.

PATRICK: And I've heard that basically they propose this and everyone agreed, yeah, we'll come up with something better, but in the end, they never came up with something that they thought was actually better, and there were more important things to do.

JASON: Yeah, no, that makes sense. That makes sense. Okay, so, we have our basic debugger running. We have some pretty gnarly just a straight array of opcodes being fired into this WebAssembly thing. But the fact that this works is extremely cool. And the fact that, you know, there's no additional dependencies here, we just whatever this is, you know, 100 bytes of opcodes, into this WebAssembly call and we're able to get addition out of that. Pretty neat!

PATRICK: It's pretty cool. Yeah, there's one more thing we can do. We can actually change one of those opcodes at the end. Let's change the addition to subtraction and then move on. Go to the end of the uint8, change the 106 to 107. Which is subtraction. Subtraction instruction.

JASON: So, once I do this, I should expect to see then we're going to get a 1 and 10 if we're subtracting properly.

PATRICK: Yes.

JASON: Very cool. That's very cool. I love this stuff. This is like this is such a rare treat to just, you know, who has time to dig into the byte code? Not me.

PATRICK: There's one more thing I want to show you here. Delete just delete one of the numbers in the array. I kind of want to show why. Yeah. Yeah. And then run the code again.

JASON: Out of bounds.

PATRICK: Yeah. One of the really nice things about working with WebAssembly is there is a validator that basically if you mess up in, you know, 80% of the ways you can mess up the validator will catch your error. So, for example, if we were to try to add without, you know, having a number, if we just had the add instruction and removed those local .git instructions, it would give us an error. Yeah. I mean sometimes you can argue the errors don't always tell you exactly what.

JASON: Not exactly solving problems, but they are at least letting you know that there are problems.

PATRICK: Yeah. Okay, if you scroll up to the top of this page then, I think we can now move on to the less sort of the less unhinged stuff.

JASON: Okay. So, just to recap what we've done here is we started with like hard mode. We took a simple addition function, that had been compiled into WebAssembly and looked at the raw bites of the file, which are here. Looked at what those would look like if they were converted into an uint8 array in JavaScript, and ran it straight in the browser here by passing in our array. Here's our Wasm pass into this WebAssembly, .instantiate, which lets us run addition, and this is the output of that. So, really cool that we were able to do that and that we modify it right in the browser. It's just neat. It's just neat. So, this is a compiler in a tweet. Already now I'm scared.

PATRICK: Don't worry, don't worry. This is really more of a party trick. We had this blog post called, yeah, a WebAssembly compiler in a tweet, and those first four lines, that's the compiler.

JASON: That's the whole compiler.

PATRICK: We're going to work with a nicely formatted version of this. So, you can click on deobfuscated, and we see something that is hopefully already a lot easier to understand, but we still have this sort of somewhat scary array of bytes, you know, down at the bottom, but we at least have something that we didn't have before, which is that we have this instrs variable, which is our actual instructions. So, we're going to create a module here that has one function again and that function this time is going to evaluate an arbitrary arithmetic expression. And we have a bunch of kind of nonsense that we need to, you know, use to pack our instructions into a valid WebAssembly module. But, you know, we don't need to worry too much about that. So, there's an even less obfuscated version of this if you scroll back up to the top. Yeah, click on that. This is basically yeah. All this stuff is basically the same, but we have now a bunch of comments, which just explain what all these different bytes are in the module.

JASON: Right, so, we talked about the magic number.

PATRICK: Yeah.

JASON: Okay, so, the next the version number. Got it. And then we say oh, this is why we were getting the notes about being out of range, is because when we were deleting numbers at random, it's saying this is five bytes long and we were deleting it. What do you mean? You didn't send me enough bytes. Okay, so, now that error message is actually a little more interesting, because before I thought it always sounds like computer nonsense until you know what the computer nonsense means, but it's good to know. So, let me see how far I can get before I get lost here. So, we're saying there's a section so, this is section one. We have five bytes in the section. Number of entries that follow, I assume is referring to this additional function section. And then we're saying that it is a function that takes zero arguments and returns one value of a type integer. And the function section size is 2 bytes. One additional to follow. And I'm guessing that's because it's referring to this one, index

PATRICK: Maybe the comment is a little bit confusing here. Each section is basically a vector or an array of something. The function section is an array of functions, and that's basically that third number is just the array size. How many functions are there. There's one. How many type declarations are there? There's one.

JASON: Oh, I get it. I get it. So, this this is saying that like the function okay, I'm kind of following. Yeah, mostly.

PATRICK: Basically, in the module there's this kind of clear or well defined order in which the various sections need to appear. After functions the function section is just function declarations. You just say this is how many functions there are in the module and this is what their types are. Then we have an exports section here, which is where we end up giving the names to any functions that we're exporting. If you scroll down a bit more, we have the codes section, which is I think the most interesting one. And there will be one entry in the code section for every function in our module.

JASON: And we're building that manually, and that's up here where we do this. We're looping over each of our... let's see. What are we looping over, actually?

PATRICK: Scroll down to the bottom here and I'll show you kind of what the goal here. So, you see this expression. Below the code we have an expression, where it says 1, 1, and then plus. So, have you ever are you familiar with reverse pollution notation?

JASON: I no, but I'm assuming we're saying argument, argument, and then what to do with them?

PATRICK: Exactly, yeah. So, there's actually they used to make these calculators that a lot of engineers really loved, apparently. I mean, it's before my time, but I've heard about this. They worked in this way, yeah, you give argument, argument, and then operator. What's really nice about that is you don't need to use parentheses. So, you have this is what's called the stack model, and this is also the way WebAssembly works. You have this sort of hidden stack. Whenever a number appears, we just push it to the stack. So, the meaning of this expression, one, space, one, means push one to the stack, push another one to the stack. Then the plus we'll take two arguments off the stack and leave one argument on the stack.

JASON: Okay. So, we get in our expression. We split that on spaces.

PATRICK: Right.

JASON: And then we say if it is a number, then we this is the opcode for setting it as like an int?

PATRICK: Basically just for a number. So, it's it's called pushes the number to the stack, and what we're going to do with that, unknown.

JASON: Got it. And if it's not a number, we use the opcode based on what type of array we're going to do or default to addition if somebody gets in nonsense.

PATRICK: Yeah, I don't know why yeah. I don't know why we default to addition. We should probably throw.

JASON: So, my question then is did I break it, because the math is wrong.

PATRICK: Good point. Did you break it? Did you change something here? Maybe I broke it.

JASON: I don't think I did, but I don't know.

PATRICK: Do you want to reload the page?

JASON: Yeah, let me reload the page and get to deobfuscated. Is it giving us a number? What if I do a different thing... let's do...

PATRICK: Can you put 3 and 7 as the and plus. Must just be yeah, we must be dropping something here. Well, there's two things we could do. Do you want to look at the deobfuscated version first and just make sure that one has the same?

JASON: That one's doing the thing. So, must just be some small typo in here.

PATRICK: Yeah, exactly. So, why don't we grab the code from deobfuscated. So, the one that works. Unless you want to have a really, you know, hair pulling debugging session. You can just grab this whole code and we can stick this in a file and start to hack on it.

JASON: Yeah, let's do it. Let me get a new a new one open. Where are we? Let me set up a new folder real quick. We're going to go into GitHub and make a new directly. Wasm please stop. Let me start a new file. What should I call the file?

PATRICK: Whatever you'd like.

JASON: It's a JavaScript file. Got it. We're looking at here's our file. We've got it running, and theoretically speaking we can execute this in the browser somewhere. You've got to chill.

PATRICK: What we could do is install, if you want to do a NPM init, then install a library that will make that will free us up from ever having to write the raw opcode. So, @Wasmground up.

JASON: Let me get into this init.

PATRICK: Slash emit.

JASON: What am I doing? That's not how any of this works. Okay, I remember how to code. We've got we've got the Wasm ground up installed at version 2.12. Do we want to add a script to run it?

PATRICK: Sure, yeah, I mean a test script maybe is nice, like a proper test.

JASON: We can just use the actual tests and that would do just run it like node?

PATRICK: Yeah, whichever. Oh, except node test, test. That should do the trick. I don't think the test does anything if you specify on the command line.

JASON: Really? I've never used it. I don't know what it does.

PATRICK: It finds test files, basically.

JASON: Oh, interesting, okay. Yeah, all right. I'm into that.

PATRICK: Thing is then you need to have something called index.test.JS or something, but I think we probably just want to have one source file and we can stick the tests at the bottom.

JASON: Keep it easier, yeah. PNPM. Nothing yet. We're missing...

PATRICK: Oh didn't we just run this and it worked?

JASON: Could have swore we ran this and it worked. It's also not complaining.

PATRICK: Do we need to type module?

JASON: Oh, I bet we do.

PATRICK: That looks better.

JASON: That's rolling. We get to, because it was trying to run at CJS, which it didn't like something about that. I'm not going to stress about that. We're okay, we got a module.

PATRICK: Yeah, sounds good. Cool. So, let's see. I mean, we can so, we can do an import at the top here and import the basically, the library that we added gives a bunch of nice, like, constants for opcodes and stuff. You can implement star as W, is the way I like to do it.

JASON: Okay.

PATRICK: And then we could go and change those opcodes there, so the 106, 107, 108, 109. We could change to w.i32.add. Actually, sorry, that's not quite right. We need to declare a constant at the top of the file. Or just outside of this constant. We need const and then open squiggly instr, like short for instruction. Equals W.

JASON: Equals W.

PATRICK: Yeah. Just because in the library we have all the instruction opcodes under instr. So, instr.w.i32.add.

JASON: Is this mul? And I'm guessing div.

PATRICK: This one is going to be fun.

JASON: Signed or unsigned?

PATRICK: Yeah, that's right.

JASON: Okay, do we care?

PATRICK: I don't think we really do in this case, no. You can probably choose unsigned.

JASON: Unsigned.

PATRICK: Yeah. I don't think it's going to matter for us, because I don't think we can actually type negative numbers in our code. And we can also fix up our i32.const down below. So, where we have 65 there, we can actually do instr.i32.const. And hopefully everything still works.

JASON: Let's run it and find out.

PATRICK: Yeah!

JASON: Okay, we're cooking here. So, this is good. Then we can this one can go back to add and we start getting some good stuff going here. Starts to make a little more sense.

PATRICK: So, we could add like a new operator here. So, I don't know.

JASON: What about this guy?

PATRICK: Yeah, sure.

JASON: And what is this one called? This is called the mod?

PATRICK: Mod, but I think the instruction is actually called rem for remainder.

JASON: Okay, we'll stick with unsigned. Theoretically speaking, down here I can do let's go 5, 3, mod, and that gives us a 2. So, there it goes.

PATRICK: Did you see that?

JASON: There it is. So, yeah. That did the thing. Exactly what I wanted. Good, good. Good.

PATRICK: You just added your first instruction to your brand new compiler.

JASON: We have done it. We've dug in here. So, just to recap how this works, because I feel like we went a little bit fast, and I want to repeat it to make sure it sticks in my brain. What we're doing is we're passing in this is our call. We're saying calculate this expression. We're using a format that says take a number and then take the next number and do whatever the instruction is, and so in this case we can change it to, for example, multiplication, and we should see 15. And if I scroll up, we do, there it is.

PATRICK: We can stack more things after that time, right. So, it's not restricted to just using one operator. So, after that you can do two and plus or two and times, so we should get 30 now.

JASON: So this gives us 30. Let's try it.

PATRICK: Because the times is going to take two arguments off the stack and put the result on the stack. And then we push another two, then the next multiplication takes those off the stack again.

JASON: And what if we do like can we do like three things, so if I do, for example, 2, 2, 2 plus, that's just going to work, right? Maybe?

PATRICK: Stack is too big.

JASON: Okay, so, we are setting

PATRICK: We need to consume no, it was okay what you have, but the problem is that you never consumed the last thing on the stack. So, if you put another plus after this, after the last plus, so if you 2, 2, 2, plus, plus.

JASON: Oh, oh, I understand. Got it. Oh. Now this is chaos mode. It's not the order doesn't matter. Well, the order matters in terms of the numbers are operated on in order and the operations are done in order. But the order the numbers and operators are in, in the sequence, does not matter as long as there's enough in the stack by the time the first operator hits.

PATRICK: I mean, it matters, it's just not obvious what it is I mean, for add it doesn't matter, right.

JASON: We start adding a bunch of different things in here, as long as we put in one, two, three, four, five, six, seven operators, this will execute, even though this is very, from a human standpoint, pretty not un parsable.

PATRICK: Yeah, exactly.

JASON: I get it, okay. I'm with ya.

PATRICK: And this is, if you're looking at so, this is actually the the underlying model for WebAssembly, is this stack machine. And the reason, you know, we're able to do a compiler in a tweet was we're leveraging the fact that the expressions, the expression language that we accept, has the exact same computational model as WebAssembly. Right. It would have been much harder here if we wanted to have expressions that look like I mean, not much harder, but probably wouldn't have fit in a tweet I guess is the thing.

JASON: Right, right.

PATRICK: We wanted to have, yeah, expressions that look like the ones you learned in math class.

JASON: Right, because we need to understand like parentheses. We would need to understand the order of operations, so that you could say go find everything that's division and multiplication first and then do the stuff that's addition and subtraction. And it's not necessarily harder. It's just more cycles.

PATRICK: Yeah, and I mean we would have probably built a tree, and then had to walk the tree. This is where you get into, you know, in compilers, things like abstract syntax trees, things like this. And we've done something that's so simple here that, you know

JASON: I do love a good abstract syntax tree. It's one of the only low level things I actually understand, so I always get excited, because I get to pretend like I know what's going on.

PATRICK: I mean, now you understand a lot more low level stuff, right?

JASON: Yeah, I mean, this is very cool that this is kind of working the way that it's working, because, again, for everybody who's maybe just tuning in now, the only thing we've got in here is this is the program. And we are putting in the length for how many instructions are being added. And our list of instructions, which is being built right here. That's very cool. It's just very cool that this works the way that we expect it to, despite being very little actual code. Because I think the other thing that's important about this is, like, when we run addition in JavaScript, we're not performing the addition, right. We're sending like the symbol of addition in JavaScript that then has to be compiled by the browser into something like this that says, hey, browser, do the addition, you know. And if you ever look at how JavaScript breaks down, if you look at the way a parser or compiler works, it's not, you know, this is not very much code, is I guess what I'm getting at. And, so, this is very cool that you can get this much going, and that, you know, now that we've been doing it for a little bit and I know I ignored this block, things aren't as opaque as I expected them to be. Let me walk away for more than 30 seconds and it will immediately exit my brain, but now I'm starting to understand how different things fit together.

PATRICK: Yeah, nice.

JASON: We have about 15 minutes left on the clock. Are there specific things you would like to dig into for this last little stretch here?

PATRICK: One thing that's interesting to talk about is, you know, how you can actually affect the outside world with WebAssembly, right. We're doing something here, which is very, you know, okay, we're just calculating a number and it's a little bit hard to go from make the leap from that to understanding, you know, how does Figma do useful things with WebAssembly in their app. And, yeah, we can begin by talking also I have a demo we could look at and we could jump into it in the debugger again, too. But, yeah, just briefly, basically, when your WebAssembly module, if you want to be able to affect the outside world or affect even sort of the browser world, right, there's really only a couple different ways they can do that. One of them is imports. So, when we create the module, the module can declare that it imports something. So, even something as simple as like printing to the console, right, WebAssembly cannot do natively. So, if we want to print to the console, you need to import. You need to say I need a function called console.log or print or whatever you want to call it.

JASON: If we want it to ask for an argument, maybe that's more than we want to get into, being able to pass things in and out to say, like, I want to run this function from the module that I wrote, but I actually want to use it in like a JavaScript file.

PATRICK: What do you mean?

JASON: I guess we're doing that here, where we're doing this is our Wasm thing. So, maybe I'm just answered my own question, so I'm going to let you keep talking.

PATRICK: Sure. Yeah, so, we can import. So, one of the ways we can sort of get access to do interesting things, like fetch is maybe a more interesting example, right. You might have a WebAssembly module that wants to be able to actually make a network request, right. We need to basically pass in give it the capability to do fetch. So, if you scroll down to where we instantiate the module, so where we have return WebAssembly.instantiate, the idea is that if in the binary encoded module it said I need I import a thing called fetch, then when we instantiated the module, we would have to give it fetch. It has no way of knowing that does what it thinks it does, but we give it a thing that has a name that it asked for.

JASON: Uh huh.

PATRICK: So, that's kind of the most basic way of doing imports or, sorry, of affecting the outside world.

JASON: Okay.

PATRICK: The other thing that a module can do is modules can read and write a protected area of memory. So, when we create the module, one of the things we can do is say, hey, it needs memory, and we can say it needs we can even say how much memory it needs. And what we can do is to actually write this is like old school 8 bit console programming or something used to work this way. You want to render something to the screen, here's an area of memory, write some bytes into it, and we will display those on the screen for you. So, you can use a pattern like that, as well.

JASON: Got it, okay, I'm with you.

PATRICK: Yeah.

JASON: And, so, the way that and can you do that do you have to allocate the memory ahead of time, like when you write the program, or is it the sort of thing where if I'm going to upload an image and I wanted one on some kind of processing on that image, I can tell the WebAssembly program, like, you're going to allocate memory and the amount of memory you're going to allocate is let me get the size of this image and send that as my call and it says, great, I'm ready for image that's this big and then you pass that into processing, or is it more like I can accept up to this many bytes and you have to pad it out or something?

PATRICK: You can do both. Basically, we can either from the outside we can grow the module's memory for it. So, the general idea is you assume the program on the outside is like the controller, right. So, and the program on the outside here is just our JavaScript code. And it can it has the ability to it's in the end the one that's going to give the module its memory, because you can import memory much like you import a function, and the JavaScript code can also say, oh, I'm going to grow your memory for you, but the module can also itself request to grow memory. And that will just happen automatically then. So, you can kind of do it both ways.

JASON: Okay. Cool. Okay. Very cool.

PATRICK: Maybe a quick demo if you go back

JASON: I'm guessing we don't have time to build it, so let's go look at it.

PATRICK: Yeah.

JASON: Okay.

PATRICK: And if you just change the URL here and add slash canvas, so slash Jason slash canvas.

JASON: This is very web GLE.

PATRICK: Exactly, yeah.

JASON: Okay.

PATRICK: What this is, is two different WebAssembly modules that are basically responsible for not rendering the pixels, but deciding on the values, the colors that those pixels should have. And one of them is working just like I described by writing to memory. And, basically, on the JavaScript side, we have request animation frame and every frame we read the memory and then stuff it into the canvas's image data. So, we could look at the code if you want to see what that looks like from the JavaScript side.

JASON: Are we looking here or are we looking...

PATRICK: Yeah, under sources. You could click on the app JS too, yeah. It's in here. So... yeah, so, you see the draw screen there.

JASON: So, draw screen. Draw, which comes out of the setup export.

PATRICK: Yeah, so, basically, that tells first tells the WebAssembly module it's time for you to draw a frame. And the after the WebAssembly code has run, we just fill take whatever it wrote to memory and stuff that into the canvas. So, yeah, this Wasm setup export function is interesting. Because it shows us the module is actually exporting its memory. That's what mem is. And then on the JS side we're using so, on the JS side you can access a module's memory, again, just as a big typed array. So

JASON: Right. And, so, I'm drawing the pixel. So, this is this is very similar to like web GL, where we're getting the red, green, blue, and alpha as like a four byte value and then we've got a Y value, an X value, and I'm assuming the way that this is working is it's basically saying you've got a space of say 200 pixels by 200 pixels, loop through this, and for each pixel, 00, 01, all the way to 200. Calculate a value and then use its current position and time and whatever you want to sort of modify that value.

PATRICK: Exactly, yeah.

JASON: Okay. So, that part, if you want to older episodes of Learn With Jason on drawing and the canvas, there's Web GL stuff, there's some other a really good one with Schar Stiles where we do visualizations of music that get way more into how the visualization part of this works. And then on WebAssembly side, what we are seeing here is that you're able to offload all of that into the Wasm file.

PATRICK: Yeah, and that could be on a worker. You could have a web worker that's actually running that Wasm if you wanted.

JASON: Uh huh. Yeah, there's a lot going on here. This is extremely cool. So, I know we barely scratched the surface, but unfortunately we're out of time, so I want to dive into really quickly showing everybody additional resources. So, let me first I'm going to link back to your book again. This is the book on "WebAssembly From the Ground Up" you co wrote with Mariano. We have a discount code set up if you use the code Jason, you get a discount on the book. Are there any other resource that is you recommend for people if they want to dig in and learn more?

PATRICK: Yes, so, the MDN documentation on WebAssembly is really good.

JASON: Here we go.

PATRICK: Yeah. WebAssembly.org is a site that is run just by the WebAssembly community group, has a bunch of resources. If you get into the point where you're sort of curious about upcoming features and things like that, this is a good place to go.

JASON: Yeah, I see specs and feature status, that's useful if you're wondering. Very cool. And then anything else?

PATRICK: I mean, people can find me on Bluesky and Mastodon or find me at Dubroy.com. Yeah, my Bluesky is also Dubroy.com.

JASON: Cool, let me get your actual website going here.

PATRICK: I'm lucky enough to have an uncommon name.

JASON: Yeah, me, too, I'm one of one of the Jason Lengstorfs in the world. Okay, Patrick, thank you so much for taking time with us today. This was super fun. I'm always grateful when something that feels so intimidating can you just get somebody to kind of walk you through the steps. So, if this is any indication of what it's like to kind of learn the rest and the book, that's a good time. I'm looking forward to seeing how people maybe try to incorporate this a little bit into their lives and see what kind of cool work you can do if you're not forced to do it all directly in JavaScript or ship everything off to a server. Any words of wisdom for everybody before I take us home?

PATRICK: I don't think I have any words of wisdom, sorry.

JASON: Well, thank you.

PATRICK: Had a lot of fun.

JASON: Thank you to everybody watching. As always, please like, subscribe, share this with somebody. We are always looking for new people to come on the show, so if you or someone you know is working on something cool, please do hit us up and maybe we'll do an episode of Learn With Jason. For now, that's all we got. Thank you so much, and we will see you next time.