---
title: On WebAssembly killing JavaScript
date: 2020-02-11
layout: post
lang: en
ref: on-webassembly-killing-javascript
---
When discussing WebAssembly (WASM), I often see people portraiting it too much
as a JavaScript replacement, but I think this framing misses the point of some
of the aspects on how WASM can be a great tool: being a portability oportunity,
which means increasing the reach to code.
If you think of WASM strictly as a optimization of JavaScript, that's where
you'll end up: WASM is the same as JavaScript, but faster.
But there's a more interesting aspect (to me) of it: portability. That means you
can now write multiplatforme code that runs everywhere. I mean, everywhere, even
in the browser. Let's imagine how you could write SQLite and mke it run on the Web.
# SQLite
If I were to create, say, SQLite today, I would consider adding web support for
it. SQLite already is available almost everywhere[^1]. This is due to it having
very so few dependencies,
Imagine having writing SQLite today
There are also other legimate uses of WASM, such as WASI and etc.
Here's how I would start writing an application that could run on any POSIX
system and, on top of that, could run on the browser:
```
// api.h
extern void platformDependentPersistInt(int);
extern int platformDependentRetrieveInt();
// api-posix.c
/* POSIX implementation of "api.h" interface to be used in non-web contexts */
#include <stdio.h>
void platformDependentPersistInt(int n) {
FILE* fp = fopen("/tmp/persisted.txt", "w+");
fprintf(fp, "%d", n);
fclose(fp);
}
int platformDependentRetrieveInt() {
FILE* fp = fopen("/tmp/persisted.txt", "r");
int persisted = fgetc(fp);
return persisted;
}
// api-wasm.js
/* WASM implementation of "api.h" interface to be used in web contexts */
export const platformDependentPersistInt = (n) =>
localStorage.setItem("persisted", n.toString());
export const platformDependentRetrieveInt = () =>
parseInt(localStorage.getItem("persisted"));
// add.h
int add(int a, int b);
void persistInt(int n);
int retrieveInt();
// add.c
#include "api.h"
int add(int a, int b) {
return a * a + b;
}
void persistInt(int n) {
platformDependentPersistInt(n);
}
int retrieveInt() {
return platformDependentRetrieveInt();
}
```
```
// main.c
#include <stdio.h>
#include "add.h"
int main() {
int added = add(4, 5);
printf("Adding 4 and 5: %d\n", added);
persistInt(6);
int persisted = retrieveInt();
printf("Persisted number: %c\n", persisted);
return 0;
}
// index.html
<script type="module">
import * as api from "./api-wasm.js";
WebAssembly
.instantiateStreaming(fetch("add.wasm"), { env: api })
.then(({instance: {exports}}) => {
const added = exports.add(4, 5);
console.log("Adding 4 and 5:", added);
exports.persistInt(6);
const persisted = exports.retrieveInt();
console.log("Persisted number:", persisted);
});
</script>
```
In order to
```
// server.py
#!/usr/bin/env python
import SimpleHTTPServer
import SocketServer
PORT = 8001
class Handler(SimpleHTTPServer.SimpleHTTPRequestHandler):
pass
Handler.extensions_map['.wasm'] = 'application/wasm'
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
```
Dependency graph:
api-posix.c api-wasm.js
api.h
add.h
add.c
main.c index.html
Compiling and running the POSIX code:
```shell
$ clang -o add main.c add.c api-posix.c
$ ./add
Adding 4 and 5: 21
Persisted number: 6
```
Compiling and running the WASM
```shell
$ clang \
--target=wasm32 \
-nostdlib \
-Wl,--no-entry \
-Wl,--export-all \
-Wl,--allow-undefined \
-o add.wasm \
add.c
$ ./server.py
```
After opening the browser, the console shows:
```
Adding 4 and 5: 21
Persisted number: 6
```
Rust, C, Zig
No Emscripten, no GC, no runtime
Emscripten 11KB
# Limitations
"System call" cost in WebAssembly.
WASM is very new, no flush guarantees.
Confusing dependency tree
AFAICT you can't package WASM with JavaScript.
[^1]: [Platforms supported by SQLite are](https://sqlite.org/features.html):
"Android, *BSD, iOS, Linux, Mac, Solaris, VxWorks, and Windows (Win32,
WinCE, WinRT) are supported out of the box. Easy to port to other systems".
https://sqlite.org/selfcontained.html