Calculated .. World
The exact same WebAssembly downloaded lazily running at the edge and in the browser. A project by Patrick Smith.
For decades CDNs have reliably served static content close to users. And now the edge brings the ability to run code close to users too. But wouldn’t it be great if adding new code was as easy as uploading an image? Sounds like a security hole waiting to be exploited right?
WebAssembly allows code to be run safely in a sandbox. And the same WebAssembly can run on a server, in a browser, or even directly on-device like your phone.
The dream of universal code doesn’t have to be only by using JavaScript. We can have a new cloud-first ecosystem of libraries, ones that run in every popular programming language, that are consistent across all environments and front/back-ends, and can be downloaded on-demand from a simple URL.
Server-rendered HTML
- Counter
A 498 byte wasm module renders this initial HTML on the server. Unfortunately it’s not interactive — see the next section!
<output class="flex p-4 bg-gray-800">0</output> <button data-action="increment" class="mt-4 inline-block py-1 px-4 bg-white text-black rounded">Increment</button>
Server-rendered HTML with client interaction (click on things)
- Interactive Counter
The same 498 byte wasm module renders initial HTML on the server, then the same wasm module is loaded by your browser where event listeners are attached, which call functions exported from wasm, changing its internal state and re-rendering the HTML. Click Increment to see!
Below is the initial HTML rendered by the server. The outer
<wasm-html>
custom element is run in the browser, loading the wasm URL atsrc
. The inner HTML is the output of running the wasm module on the server, providing the initial HTML.<wasm-html src="/collected-public/wasm/a8e931832cc7dce187d7234237f6cfef13e9fa523ab4101d3cec7bfb66e905c1"> <output class="flex p-4 bg-gray-800">0</output> <button data-action="increment" class="mt-4 inline-block py-1 px-4 bg-white text-black rounded">Increment</button> </wasm-html>
Event delegation is used to automatically wire up the button’s click to call the
exports.increment()
function exported from WebAssembly. How does it know which exported function to call? See thedata-action="increment"
? That declares the exported function’s name to find.So we have a single WebAssembly module, running in two places (server and browser), able to generate the initial HTML and the updated HTML after interactions. And the interactions are handled by what was declared in that initial HTML — it’s all self-contained.
SVG
View HTML
<img
src="/collected-public/wasm-svg/a6e388fd5d780de90144044066d2eeb889c1f930c85b1fff0a6b530fad391f20"
alt="Black Square"
/>
View HTML
<img
src="/collected-public/wasm-svg/a6e388fd5d780de90144044066d2eeb889c1f930c85b1fff0a6b530fad391f20?global.color_hex=0x2299ee77"
alt="Blue Square"
/>
How does it work?
What else can you create with WebAssembly?
- State machines that run in any major programming language.
- HTML Components that run in the browser, on the server, and on the edge.
- Parsers and formatters that run really fast.
- Localized text that is code split and efficiently downloaded on-demand.
- Sandboxed user-generated code.
- Don’t just settle for inert JSON — how about Turing-complete payloads served from a HTTP API?
- Maybe even minature apps store as TXT records on your domain.
This site you fine viewer are looking at is authored using Astro in server mode, uses Deno Deploy for edge hosting, Google Cloud Storage to store .wasm files, and custom HTML elements written with a handful of JavaScript.
But this approach is tied to none of these. It could easily work as well with S3 plus Next.js running on Node.js.