29 September 2026
A modern web page is a small operating system where React landing pages load dozens of dependencies to show you a slide show and a pricing table. Yet to find out whether I like a new shiny TUI or CLI app, I have to install it via brew (or god forbid cargo) and then don't be lazy to uninstall if I don't like it.
That annoyed me enough to start wondering: if my browser can run a 40 MB landing page, why can't it run a 4 MB Linux program?
This curiosity and addiction to system programming got me sucked into the black hole of writing a hardware emulator that can run on a web page. Many months later, with long beard and red eyes I'd like to present you my solution: ARM64js.
It is an ARMv8-A emulator written in Rust, compiled to WebAssembly. It boots real Alpine Linux (somewhat tweaked but real with actual kernel, binaries, etc) inside a web page. You can use it as you would a normal Alpine: run apk, install software and even run docker (don't expect too much of performance in this virtualizeption though).
Why Arm? Because it's easier to emulate -- it has more predictable instructions (same size) and is easier to "parse".
One wasm module is loaded into a few web workers that share one block of memory: that memory is the VM's RAM. Emulator supports multiple vCPUs (one worker per virtual CPU), but they are useful in very rare cases and in general make things only slower (due to shared memory being slower).
Living inside the browser brought some unexpected challenges:
Considering the level of emulation I think it ended up quite ok:
| Boot to a shell from a snapshot | 2.5 s on 50 Mbit/s, 1.3 s with no download |
| Typing lag in the shell | 8 ms |
| Typing lag in vim | 37 ms |
It's like your old 2000s PC pretty much. So you not gonna compile a Rust app on it, but can def run some TUI apps, golang servers, etc. Even Python or PHP feel quite ok.
Check out the readme for more info but in general it takes a couple of lines to get one running. SDK knows how and which wasm to load, making it easy to start.
import { Arm64JS } from 'arm64js';
const vm = await Arm64JS.boot('alpine');
const { output, exitCode } = await vm.exec('uname -a');
console.log(output);
There is free tier and it's free for OSS projects.
Go to arm64js.com, there you can learn more about the tech but also try a few prebuilt VMs to see it in action. Drop me an email to info[at]arm64js.com if you have any questions or buzz in Discord.