How to turn your Website into an App (and why maybe you shouldn't!) with Russell Keith Magee
Published November 3, 2022
This video features Dr. Russell Keith-Magee at DjangoCon US 2019 in San Diego, California, USA.
DjangoCon 2019 - WASM matter? by Russell Keith-Magee
One of the biggest developments in web technology in the last few years is the emergence of WASM - Web Assembly. But what is WASM? Can you use it in your web projects? Should you? And if so... how?
This talk was presented at: https://2019.djangocon.us/talks/wasm-matter/
LINKS:
Follow Russell Keith-Magee 👇
On Twitter: https://twitter.com/freakboy3742
Official homepage: https://cecinestpasun.com
Follow DjangCon US 👇
https://twitter.com/djangocon
Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/
Intro music: "This Is How We Quirk It" by Avocado Junkie.
Video production by Confreaks TV.
Captions by White Coat Captioning.
WebAssembly (WASM) provides a portable binary format for code that runs in browsers, allowing languages other than JavaScript to target the web. Russell Keith-Magee explains how WASM evolved from JavaScript optimization techniques such as asm.js, how its low-level stack-based instructions, memory model, modules, imports, and exports work, and how C, Rust, and other compiled languages can target it. Current uses include porting existing C applications such as Quake, accelerating CPU-intensive browser code such as image processing, and compiling libraries for client-side use. For Python developers, projects such as Pyodide, MicroPython, Batavia, and Wasmer suggest ways to run Python or Python extensions in the browser, although substantial size and tooling limitations remain. He argues that WASM matters because it separates the web’s universal runtime from any one programming language, making it possible for Python and other languages to coexist with JavaScript rather than requiring everything to be rewritten in JavaScript.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Well good afternoon all. Yes, my name is Russell Keith McGee. I do unfortunately occasionally when excited speak quickly and I am often excited. I apologize to the transcriptionists in advance. There are voluntary organizations available. to help rehabilitate afterwards. In my day job, I am a senior data engineer at Savata. We are a brand intelligence platform. We use Python and data science to deliver consumer insights and and predictive analytics to help customers improve the impact of their brand marketing. They give me the flexibility to attend conferences like DjangoCon, which is something I'm very grateful for. Also, we are hiring at the moment, particularly for front-end engineers. So if you are looking for a change, please come Find me, I might be able to help you out there. Uh I am a long-term fixture at DjangoCon, uh, along with Andrew Godwin.
We are the only two people who have been to every DjangoCon US. I joined the Django Core team way back in 2006. I'm not as active in the Django community as I once was though. And there's many reasons for that, but at least one of the reasons is the way that the web has changed. Over the last few years, web development has become extremely JavaScript heavy. And there's absolutely nothing wrong with JavaScript. As a language, I just happen to prefer Python. 15 years ago when I started using Django, you could almost ignore JavaScript. You know, your logic was client-side was all server-side. The client was just navigating through a series of pages that you know may have been generated from dynamic content, but they were static when they were delivered to the user. It's a lot harder to ignore JavaScript these
days. Users expect a rich client side experience and JavaScript's the only language that's available in the browser, so that means we need to use JavaScript. Note though that I say use JavaScript, not necessarily write JavaScript. What I'd like to talk about today is a development in the JavaScript ecosystem that has the potential to reduce the significance of JavaScript as a language and open up more opportunities for Python and by extension Django. That development is WebAssembly or WASM. Now to explain what WASM is, you have to dig a little bit into how you actually get code running on a computer in the first place. When code runs on your computer, it's running as machine language, binary instructions. specific to a particular CPU.
Those binary instructions aren't especially easy to write, so one of the first programming interfaces was assembly language. Assembly language is a human readable version of machine language. Every machine language construct is exposed directly as an assembly language analog, so assembly source code can be easily assembled into a machine language binary executable. Now I say human readable. Assembly code isn't that easy to read, or write for that matter, and so developers wrote abstractions. The first level of abstraction comes in the form of compiled languages like C. In a compiled language, you take your source code, you run it through the compiler, and that produces the equivalent assembly language which can then be converted into machine language to produce an executable. Modern compilers will often just go directly to machine language output, but internally the same thing is effectively happening.
When you send a C program to someone else, what you're passing around isn't the C source code, it's source code converted into a machine language format so that it can run on that particular CPU on that particular computer. It doesn't contain any remnants of the original source code. That compiled executable form is tightly bound to one specific CPU architecture and to the The specific libraries provided by a specific operating system. The next level of abstraction is the interpreted language, like JavaScript. Now, when you send a JavaScript program to someone else, what you're sending is the source code. But at the end of the day, the computer does everything in machine language. The interpreter itself is a machine language native executable that can read the source code and interpret the machine language consequences of the source code it has been given.
The benefit of this approach is the code you pass around isn't machine dependent. The same JavaScript source code runs the machine the same everywhere because it's the interpreter that does the hard part of working out what machine language instructions are needed on this computer to provide the desired effect. Now, let's say we're using JavaScript, we've written ourselves an add function. It takes two arguments, it adds them together, and it returns the result. When this is run through a JavaScript interpreter, the interpreter has to convert it into CPU instructions. But which CPU instruction? Now if first and second are integers, then we need to do an integer addition. If first and second are strings, then we need to do string concatenation. If it's two completely different types, then you know it gets even more complicated.
That means that the interpreter has to be ready to do almost anything because the code will allow you to do almost anything. And it has to work out what it's doing at runtime. The price you pay for that flexibility is that your code is a little bit slower However, because JavaScript is now so important to the end user experience in the browser, the runtime performance of JavaScript engines has seen a lot of attention. Once our code starts running, we might find that because of the way the code is being invoked, the arguments are always integers. And the interpreter can exploit that. It can see that our add method is only ever being invoked with integers and therefore come up with an optimized interpretation of the add method
that will only ever do integer math. Because of that narrowed scope, the optimized version is faster because it is dynamically adapting to every possible input type, which makes it closer to the bare machine language instructions the computer actually needs to execute Now this is effectively the same thing that a compiler does on a compiled language, but it happens at runtime. And for that reason, the process that's going on here is called just-in-time compilation, because the conversion to machine language is happening just in time for the code to execute in contrast to ahead of time compilation of a compiled language. So a Jitting interpreter, a just-in-time interpreter, will optimize the code at runtime to make it run faster. The question then becomes, can we game the system?
Can we do something to our code that will make it easier for the interpreter to identify possible optimizations? And it turns out the answer is yes. For example, in JavaScript, the result of a logical OR with an integer is always an integer. If you OR an integer, or if you OR with an integer of zero, you get the original integer. So if we OR both of our functions' arguments with zero, the interpreter can know That the addition operation must be an integer operation. It doesn't matter what the types of first and second are, the addition is an integer addition. And because of that The JavaScript engine can easily identify that it can optimize the implementation of this method and only do interjuridiction, something that has a direct interpretation in machine language
and is therefore fast. Okay, that's a neat trick, but why do we care? After all, we have to you know deface our code pretty badly to be able to realize that optimization, so you know, is it really worth it? Well, you know, if you're looking at this as a way to speed up your handwritten JavaScript, probably not. But take another look at what we've just been able to do. By just annotating our JavaScript code, we've been able to convince the JavaScript interpreter, the dynamic JavaScript interpreter, to give us near-direct access to optimized integer arithmetic. It's a very roundabout way of expressing it, and the optimization doesn't happen until the code is actually running, but we have used an interpreted language to expose a primitive machine language construct.
If we can expose one machine language construct, can we expose all the capabilities of machine language? A few years back, a team at Mozilla looked at the JavaScript language to determine if there was a set of JavaScript code annotations and conventions that you could use to trick a jitting JavaScript interpreter to expose near-direct access to the full capabilities of your CPU. And what they came up with is called ASM. js. ASM. js is 100% legal JavaScript code. It is not pretty JavaScript code. code. It only uses a subset of everything that's available in JavaScript, and the code is covered with annotations and weird coding conventions like the zero wars that I showed before. But in combination. Those annotations and conventions provide a set of low-level primitives to perform integer and floating point arithmetic, allocate memory, define and invoke functions, and so on.
Capabilities that map directly onto the capabilities of machine language. They have effectively defined a way to expose machine language capabilities of a CPU using nothing but JavaScript, a dynamic language, which means effectively it is a cross-CPU assembly language. But even ASMJS can be improved upon. What is delivered by ASMJS is still JavaScript code. Admittedly, it's almost entirely illegible JavaScript. code, but it and it does need to be transmitted in a text format, then parsed, then interpreted, then executed, and then jitted. If we know ahead of time that our code will be compatible with the fast JavaScript subset Can we send our code to the browser in a ready-to-use format?
And that's what WebAssembly or WASM is. WebAssembly is a binary format formalizing the ASM. js language subset in a format that can be delivered to the browser in a pre-parsed form, pre-hinted for JITing purposes. That makes it smaller to transmit than ASMJS because it is a binary format. It's faster to start because you don't have to parse any code, it's in binary format, and it's more consistent in operation because you are telling the JIT where the optimizations are. So that's how we got here. But how do we actually use it? Well, the development story for WASM actually pretty closely mirrors the story that I've already just told you about running normal executable binaries WASM is ultimately a binary format.
But unless you belong to the standing in a hammock school of programming, you're not ever going to write raw WASM directly. What you want is a human readable text-based assembly format that can easily compile into WASM. The toolchain you need to do this is called the WebAssembly Binary Toolkit. The toolkit gives you a bunch of tools for manipulating WASM code, including an assembly language compiler that lets you write Wasm code in a text format called WAT for WebAssembly Text. WAT looks like a weird hybrid between Lisp and Assembly. It is a core set of very primitive operations with a brace syntax to make scoping rules. Explicit. So here is our integer adding example in Watt. We define a module that contains a function called add.
It accepts two parameters, namely first and second, both of which are declared as being of type I32. And it also returns a 32-bit signed integer. Now, the body of the method. An executing WASM method is a stack-based virtual machine. So to do our addition, we need to load the values provided as arguments onto our stack. We get them and put them onto our stack. I do the same for this first argument, then the second argument. Now we've got two values on our stack. We can then invoke the integer add operation, i32 add, that pops the top two values off the stack, does the add, pushes a single result back onto the stack, which is the result of the addition. We're now at the end of our method. The value that is on top of the stack at that point is considered to be the return value of the method, and so we've got a return value for our add method. That completes our method definition.
We can now export that function to say, okay, this module defines the function and I want other modules to be able to see this function. And that's it. You save that as example. wat, you run a compiler called Wat2wasm over it, and you get example. wasm, which spits out as a binary file 41 bytes in size. To use that Wasm file, you need to write a little bit of JavaScript. We fetch our Wasm document, we use the payload to instantiate the WebAssembly module, and then we access the exports of the module and just invoke them as if they were a standard function. In this case, we just call the exported add method with a couple of integers. The add method returns an integer, we can do whatever we need to do with that integer. In this case we're setting the text content of an element on our page. And to be clear, this is not some theoretical future thing either.
This example will work in all of the major browsers that are in the field have been released in about the last two years. There are a couple of optimizations you can use if you're cutting down to just Chrome and Firefox, but this example as is works in IE, it works in Safari, it works in Chrome, it works in Firefox. Alright, so that's a simple addition example, but integer addition is only going to get you so far in the big wide world. So what else can we do with WASM? Well, WASM by itself is very primitive. The full WASM instruction specification is one relatively terse HTML page, and it only has five sections. First, there are numeric instructions, add, subtract, multiply, divide. There are booleans like and and or there are function operations like square root, ceiling and floor, min and max, comparison operations like equality, less than, greater than.
These can be invoked on integers and floats in 32 and 64 bit ranges, signed and unsigned. Okay, then there are variable instructions, operations to get and set variables in your local scope. There's also a T operation that lets you set a variable and keep it on the stack at the same time. Next there are control instructions, mechanisms to do uh branch control, uh looping, invoke other functions, return a value from a function. Things like that. There are memory instructions, mechanisms to allocate a block of memory for the WASM interpreter to load and store values into that memory. Memory is actually just implemented as an array of bytes. Uh the array can be grown in size but can't be shrunk, so there's no free, no, no free uh uh uh discarding of memory. And lastly, there are parametric instructions. These exist to let you discard values that happen to be on the stack you don't need anymore.
These instructions are then wrapped up in a module. A module obviously includes function definitions, but it includes lots of other information too. There are types and tables that let you describe more complex data structures. uh and reference other functions in your wasm module. Memories describe blocks of memory that can be allocated and referenced by your WASM methods. Globals define global Global variables, uh global to the module. Exports define the interface that your WASM module exposes externally, and imports describe the external functions that your WASM module will be able to invoke and depend upon. And lastly, there's space for you to define data and code that will execute when the module is instantiated. One thing you might have noticed that I haven't mentioned, any discussion of text string. That's because WASM doesn't support text strings.
A string in Wasm is handled the same way your CPU handles it. Wasm only knows about integers and floats, so to create a string, you allocate a block of memory. and you use an integer as a pointer to the position of that memory in the overall memory of your WASM instance. You use that block of memory to store a list of integers and you assign some sort of significance to the value of those integers. Be that ASCII or UTF-8 encoded code points or whatever encoding structure you want. When I say WASM exposes primitives, that's what I mean. Primitives. Remember, it's an assembly language. But just as very few people write raw assembly code anymore, very few people actually need to write raw WASM either. A much easier approach is to use a compiler for a language that can target WASM. The most notable of these compilers, and the first by some uh quite some uh uh
period, was Inscription. Inscripten is a back-end to the Clang C compiler. If you've got a language that Clang can compile, like C and almost every other language that's compiled, Inscripted and can turn that code into a WASM binary. So let's go. We'll define ourselves a simple C function to do our addition. We use an inscript and compiler directive to say this is a keep alive function. This is a function that we want to be able to export out of our module. We then use the inscript and c compiler, EMCC, to compile example. c into example. js. Now notice here we don't compile example. wasm directly. Using C means there is some overhead. There's a bunch of C-related infrastructure that needs to be set up and example. js contains that bootstrapping code.
We need to tell EMCC the name of the module that we want to export. We'll just call it example in this case, and we want to tell it that we want to export the CWAP runtime method. I'll come back to that one in just a moment. If our WASM module contained an entry point, if it had a main method, a main entry method, we could just include example. js in our HTML page, and every time the page was loaded, our Wasm module would be executed. Executed as well. However, if we want to interact with the module, we need to hook into the module's life cycle. So in our HTML, we pre-declare the existence of an example module, an example object. And we define a method to invoke when the WASM runtime has been initialized. In that method, we're going to define a wrapper for our C method, declaring the mapping from the JavaScript types to the C types.
and then return the types, uh the types in the arguments. And we can invoke that JavaScript function. Okay? And that's that's the the the role of the of the CRAP method that we expect. exposed in the last slide. We then include the example script. This will augment the pre-declared example module as example. exe uh. js is is executed. Now, for a simple example like this, that's a lot of, or there is a lot of overhead. The example, this example produces about 100 kilobytes of bootstrapping support code and about 21 kilobytes of WASM binary. However, a lot of that overhead is included just in case. And by default, C compilers optimize for compilation speed, not output size. So when you are ready to go into production, you can tell EMCC to strip out everything that isn't needed, and that dramatically reduces the payload size, and it can also minify the JavaScript as well while it's at it.
That optimization can be performed at various levels of severity. At optimization level three, the complete output of this example, this addition example is 19 kilobytes of minified JavaScript and 165 bytes of WASM, which is, yes, more than our original 41 byte handcrafted WAT derived output, but There is still you get you get do get some benefits out of that. There is still some overhead, but the benefits you get, you don't have to, one, you don't have to write assembly by hand, and things like strings are handled almost transparently You can declare a C function that takes a C string, a character pointer, as an argument, or return a C string. You can invoke C built-in methods like string lengths. or do console output with printf.
On the JavaScript side, you can wrap that function and you can invoke the function with JavaScript strings. You don't have to do an exchange back and forth and what Worry about uh the the encoding process. Nscripten also makes it easy to interact with JavaScript. Simple scripts can be just invoked directly. There is a C function called nscripten run script, and it will run JavaScript. Or you can set up a block of JavaScript as a C callable function. So here's another example. The second code block, the intmyfunk , is written in C. It directly invokes the JavaScript alert method using NS Script and run script, and then it calls the JSAD function. jsadd is defined in the first code block. ESJS is another inscript and compiler directive. It allows you to embed directly embed JavaScript code into your C source code file and expose that JavaScript code as if it was a JavaScript
sorry as if it was a C method. My funk is a C method, so when it's invoked, we will be using nscripten to compile the C function that wraps a JavaScript function that does addition in JavaScript. You also get access to a bunch of other tools and APIs that are part of the Inscription toolchain. Inscription provides bindings to HTML5 events, so you can write native implementations. of keyboard, mouse and scroll handlers. You get access to a file system API. You are still sandboxed. You don't can't read and write files from your user's file system. but you do get a virtualized file system that you can feed binary blobs and treat them as files and access them using C file APIs. You can use the browser's fetch API to retrieve other network resources, and you can access hardware optimized web APIs like WebGL and WebVR.
Now, Enscription was very much the first player in this compiled language space, but it isn't the only player anymore by long long shot. For example, the Rust compiler can compile directly to WASM. The Rust project has a really good tutorial for how to write and deploy logic for your web app completely in Rust. Alright, so that's the how you generate Wasm code, but why is WASM of interest to us as Python and Django users? Well, there are two primary use cases for WASM in production right now today. The first is deploying a full application that is written in C already. For example, if you head to Quakejs. com, you will find a full port of Quake 3 compiled and running in your browser. It does take a minute or two to download because you are downloading the whole of Quake, but once it's there, it is a fully functioning 3D first-person shooter running in your browser.
Why does this work? Well Quake is written in C code using OpenGL key and keyboard inputs. That means it maps directly onto the capabilities of WebAssembly. And so it's an easy win. You just have to recompile essentially Quake with EMCC and you get a web page you can load that is Quake. The QT widget toolkit is also working on a WebAssembly port. So if you've got a QT app, you can compile that app and deliver it over the web potentially. Now, I won't say it is trivial to do this, but the inscript and build toolchain maps really well onto the Autoconf toolchain. So if you've got a C project with an Autoconf configuration, which again is a lot of them uh compiling an existing C project for WASM can be relatively straightforward if
once you've worked out you know the little details. Use case two is to identify hot loops or critical b uh uh for business critical business capabilities and replace those hot loops with WASM implementations. For example, Google has published a demonstrator app called Squoosh. Squoosh is an app for doing image manipulation, for exploring the before and after effects of various forms of image compression, resizing, and resampling algorithms. The app itself is a node app delivering basic app scaffolding and content, but it uses WASM to implement the image processing. Almost all of your standard image codecs like libjp are written in C. So instead of trying to re-implement all of libjp in JavaScript, or having some server back and forth that is going to have some latency, which, you know, trust me, in Australia
we notice, you can just say take libjp and put it in the browser. If you've got an existing C library, you need to use client-side, you can, and you just call it as if it was JavaScript. Or if you're writing a web app that has a hot loop, a method or part of a method that is very CPU intensive. You can replace that hot loop with Wasm code written in C or Rust or any other compiled language that can target WASM. If you want to quickly play around with Wasm, the best tool I can recommend is WebAssembly. studio. That is actually a URL, not a product name. If you stick that into your browser, you will get a simple WASM development environment that you can play around with without having to download and compile any of the tool chains. If you like what you see there, then it's well worth downloading WebAssembly binary toolkit, inscription, or Rust's WASM
tooling. So those are the viable use cases today. But what does the future hold? How do we make use of Python in the WASM world? Well, if you think back to the start of this talk, I spoke about the path of getting code to run from assembly language to compiled language to interpreted languages. And then I described a similar path with WASM, defining an assembly language, compilers that target that assembly language. There's one more step to take. You can write language interpreters that can be deployed as WASM. Now I can't say this is quite ready for prime time today. There are a couple of projects exploring this space that that are worth keeping an eye on. The most notable at the moment is Pyodide from Mozilla. Pyodide is quite literally the CPython source code compiled with inscriptin.
They've also gone to the trouble of compiling NumPy and SciPy and Matplotlib, some other key parts of the scientific Py ecosystem. If you take the WASM binary produced by Inscripton compiling CPython, hook it up to the elements of a web page, the input elements of a web page. You get a Python shell in your browser, completely client-side, no server-side component. And the Pyodide demo is effectively a 100% client-side Python environment comparable to a Jupyter notebook session. It is a full Python parser, compiler, runtime, and X uh and graphics engine. The downside is that it's big. Uh the WASM file for the Pyodide version is of just C Python is around three megabytes, and that's before you've given it any Python code or standard library to run with.
So, if C Python is too big, maybe we just need a smaller Python. What about MicroPython? It's written in C. Can we compile that? Well, yes, you can, and yes, it's been done, and yes, it's on NPM. You can install via MPM a JavaScript package that provides the MicroPython virtual machine. And yes, it is small and pyodied. The official distribution is just shy of one megabyte. Both of those projects are still experimental, but they are very interesting developments. But they both take a very similar approach. They're exposing a full Python REPL in the browser. My own experimentation in this space has been somewhat somewhat different. Batavia provides Python in the browser by just implementing the CPython virtual machine. So it doesn't need to have the compiler and parser, it just needs the bits that runs the bytecode. If you take, if you transmit Python bytecode, the PYC file, the contents of your PYC files on the wire.
You don't need a compiler and a parser. You just need the bytecode machine. Batavia currently does this by implementing the CPython bytecode virtual machine in pure JavaScript. But WASM might provide an alternative here. If you were to take the CPython sources, strip out the parser and the compiler, you should end up with a much smaller Python interpreter, but one that's capable of running all CPython bytecode. And it would actually support the C Py the C module extension API. Combine that with some smart tree shaking in an entirely client-side Python starts to look plausible. And that C module compatibility is itself a point of interest. One of the major reasons that people write C modules today for Python is for performance reasons, to take the hot loop in your Python code and run it in C.
But using a C module means that your Python no longer runs cross-platform, at least not without recompiling it for each platform that you need to deploy to. But if you compile your C module code. to Wasm, you get a cross-platform native binary. All you need then is the ability to invoke it from within your Python code, which is what a Python module called Wasmer does. Wasmer is part of a larger binary project that aims to be a way to distribute Wasm code as universal binaries that can run on any platform you want. So, wrapping up. In the mid-90s, Java was the hotness because it was gonna deliver right once run anywhere code. It was able to run everywhere because it specified a bytecode format.
and provided a cross-platform virtual machine, but it strongly coupled a new programming language, Java, to that whole runtime experience. And while the world got really enthusiastic about Java, and Java isn't going anywhere, it wasn't able to completely replace all other programming languages. JavaScript was invented at about the same time, and it is called JavaScript, not because it has anything to do with Java, but for marketing purposes. To capitalize on that cross-platform enterprise-ready computing buzz that mid-90s Java had managed to develop so successfully. JavaScript was a new language, and it was cross-platform too, so by golly, it had to have Java in its name. JavaScript didn't have a standardized bytecode format or provide a virtual machine to make a cross-platform.
It only worked in the browser. But over time, the importance of the web as a platform has meant that people have tried bringing JavaScript everywhere. They have essentially reinvented uh they've tried to reinvent the universe using only JavaScript, making exactly the same mistake that Java made, focusing on the language, not the runtime. The great irony in all of this is that the promise that Java originally made, right once, run everywhere, that promise may end up being delivered by JavaScript. a language that borrowed the Java name purely for marketing purposes. But even then we're going to get the capability by ignoring the language entirely. JavaScript has the potential to actually be a universal computing platform.
Not because JavaScript the language, not because of JavaScript the language. but because of the importance of the web as a platform and all the effort that's been put into optimizing JavaScript runtimes as a result. Almost by accident. We have ended up with WebAssembly, a mechanism for describing cross-platform native executables. And that is ultimately better for everyone because it abandons the idea that there is one programming language to rule them all. Let alone let every language find its own niche and let different languages, including Python, coexist and cooperate in a universal binary world. There is a lot of work that still needs to be done before we can speak about having an experience as a web developer that doesn't actually involve JavaScript or at least only involves JavaScript as an execution platform for our Python or whatever other language you happen to want to use.
I would like to be able to spend a lot more time working on this, on Batavia, other aspects of the Python ecosystem. By way of a quick plug, if you'd like to support my work, you can join the BeWare project as a financial member, or if you prefer, you can back me on GitHub sponsors I will also be here for the rest of DjangoCon through the end of Sprints. If this or any of the other BWES stuff interests you, please come and have a chat. I'm always happy to talk about any of this and more. More. Thank you all very much.
WebAssembly is a compact binary format based on the low-level subset pioneered by asm.js. Because it is binary and pre-parsed with optimization information, browsers can download, start, and JIT-compile it more efficiently than JavaScript-based asm.js.
Discussed at 9:53You normally write WebAssembly Text (WAT), compile it with the WebAssembly Binary Toolkit into a WASM binary, and load and instantiate that module from JavaScript. The module’s exported functions can then be called like ordinary JavaScript functions.
Discussed at 10:38Yes. The basic example shown works in Internet Explorer, Safari, Chrome, and Firefox, including versions released roughly within the previous two years of the talk.
Discussed at 13:00WASM provides low-level numeric, variable, control-flow, memory, and function operations, with modules defining imports, exports, globals, tables, and memory. It deliberately exposes primitives rather than high-level features such as strings, which must be represented in allocated memory.
Discussed at 13:48The two main uses are porting existing C applications to the browser, such as Quake, and replacing CPU-intensive “hot loops” or critical capabilities with compiled C, Rust, or other WASM-targeting code. Examples include image processing in Google’s Squoosh and using existing image codecs client-side.
Discussed at 21:09Projects such as Pyodide compile CPython and parts of the scientific Python stack to WASM, providing a completely client-side Python environment in the browser. MicroPython offers a smaller alternative, while Batavia explores running CPython bytecode with a more minimal interpreter.
Discussed at 24:21Yes. Compiling a Python C extension to WASM can produce a cross-platform native binary, provided Python can invoke it; the Wasmer project is presented as one way to distribute and run such WASM code.
Discussed at 27:29Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 14, 2026