The browser is the computer

Linux is the kernel. HardwareJS is the machine.

A real Linux kernel compiled for the native WebAssembly (Wasm) architecture, booting ordinary userland programs against shared WebAssembly memory. HardwareJS provides the processors, memory, interrupts, devices, and browser integration that make that kernel useful.

boot.log
[boot] validate vmlinux.wasm
[ ok ] shared kernel memory
[ ok ] boot_info ABI v3
[ ok ] CPU 0 kernel worker
[ ok ] pool CPUs online
[ ok ] virtio-mmio devices
[init] /sbin/init

brintOS:~$ uname -m
wasm32
SPEC SNAPSHOT Rolling targets ABI v3 2026-07-24
KernelLinux
ArchitectureWasm ISA
Address profileswasm32 · wasm64
ExecutionLLVM coroutines
HostBrowser Workers
Device busvirtio-mmio

Why this machine

Put the virtual machine inside the browser’s security boundary.

Browsers spend their lives executing code delivered by parties the user does not control. Decades of sandboxing, exploit mitigation, process isolation, origin policy, permission design, and rapid patching have made the browser tab one of the most battle-hardened application surfaces on a computer. HardwareJS puts a Linux virtual machine inside that existing defense-in-depth system.

01 / BUILD Linux + userland C and C++ source
02 / TARGET Wasm module Portable virtual ISA
03 / ENGINE Validate + compile Baseline machine code, then optimized hot paths
04 / EXECUTE Host ISA x86-64 · Arm64 · RISC-V · more
01 / CONTAIN

Built for hostile code

A modern browser assumes downloaded code may be malicious. Renderer sandboxes, process boundaries, site isolation, permissions, and automatic security updates limit what a compromised workload can reach. Running the machine in a tab lets HardwareJS build on those defenses instead of introducing a new privileged native runtime.

02 / TRANSLATE

The engine speaks the local processor

A Wasm binary is not x86, Arm, or RISC-V machine code. The browser engine decodes and validates the module, compiles it to the host ISA, and executes the resulting native instructions under the browser’s controls. Engines commonly generate baseline code for fast startup, then recompile frequently executed functions with deeper optimizations.

03 / SCALE

One architecture, two address widths

wasm32 is the compact, performance-oriented profile: smaller pointers reduce memory footprint and keep common workloads inside a tight address space. wasm64 extends the same Wasm architecture with 64-bit memory indexes for machines and workloads that need a larger linear-memory address space.

04 / CARRY

Build once; carry the machine anywhere

The Wasm standard defines the program’s instructions and behavior independently of the host processor. The same kernel and userspace artifact can therefore run unchanged on any conforming browser engine that implements the required Wasm features and HardwareJS interfaces—without separate x86-64, Arm64, or RISC-V builds.

The portability contract: one Wasm artifact, one set of defined semantics, many host processors. HardwareJS supplies the explicit capabilities the module may import; Wasm code receives no ambient access to the underlying machine.

SOURCE BASIS · WebAssembly design goals · V8 compilation pipeline · Chromium site isolation


Compiler substrate

The compiler makes the stack copyable.

WebAssembly engine stacks are opaque. The hwjs-cc toolchain uses a pinned LLVM/Clang fork and the HwjsCoroutinize pass to move suspendable continuations into linear memory—giving Linux the resumable state it needs for blocking, bounded preemption, setjmp/longjmp, and fork().

Read the compiler and coroutine specification →
01ClangC / C++ → LLVM bitcode
02wasmldWhole-program merge
03HwjsCoroutinizeReifiable continuations
04wasm-ldExecutable WebAssembly

Two layers, one system

The separation is the design.

The kernel owns Linux semantics. HardwareJS owns the machine. Their narrow, versioned boundary keeps each layer understandable and lets normal kernel drivers meet real browser capabilities.

SECTION 01

Linux / wasm32

The architecture port: boot, memory, task switching, syscalls, signals, fork, exec, dynamic linking, and the wasm-facing device drivers.

  • Upstream Linux plus arch/wasm32
  • Real musl and glibc userspaces
  • No Emscripten, Asyncify, Binaryen, or JSPI
Open the kernel specification →
SECTION 02

HardwareJS

The TypeScript host runtime: WebAssembly lifecycle, CPU Workers, memory, scheduler coordination, interrupts, virtio backends, displays, networking, and physical I/O.

  • Hardware and firmware—not a second kernel
  • SharedArrayBuffer-backed machine state
  • Browser APIs exposed through Linux drivers
Open the machine specification →

Comparative landscape

“POSIX in a browser” describes several different machines.

A shell prompt does not reveal the architecture underneath it. The useful distinction is which code services a system call: a guest kernel behind an emulator, a browser runtime, a standardized host interface, or Linux itself.

The distinguishing question Who handles fork(), open(), and wait()?

This is an architectural comparison, not a benchmark or compatibility ranking. Each project chooses a different point among prebuilt-binary compatibility, portability, sandboxing, ecosystem focus, implementation weight, and operating-system fidelity.

Current approaches to Unix- and Linux-shaped execution in the browser
ApproachWhat executesSystem-call authorityPrimary tradeoff
THIS STANDARD Native Linux architecture port Linux / wasm32 + HardwareJSA wasm32 Linux kernel and wasm32 user programs execute as WebAssembly modules, with a kernel instance on each CPU Worker.The actual Linux kernel services the syscall. HardwareJS supplies CPUs, memory, interrupts, and device backends.Avoids guest-ISA translation and avoids reimplementing Linux services; software and architecture support must be built for the new wasm32 target.
Full-machine emulation JSLinux · v86 · container2wasmAn existing Linux kernel and foreign-ISA userspace run inside an x86 or RISC-V emulator.The guest Linux kernel, after the emulator executes or translates the guest instruction stream.Preserves prebuilt operating systems and binaries; carries the compute and image cost of a complete emulated machine.
Application toolchain EmscriptenAn application is compiled to WebAssembly together with generated JavaScript and runtime libraries.Emscripten’s libc and runtime map supported operations onto virtual filesystems, Workers, and browser or host services.Excellent for porting an application to the web; it does not attempt to supply a general Linux kernel and process model.
Browser Unix kernel BrowsixPrograms built for extended C, C++, Go, or Node runtimes execute as browser processes on Web Workers.A TypeScript kernel maps processes, pipes, signals, sockets, and a shared filesystem onto browser APIs.Composes Unix programs without CPU emulation; the Unix semantics are supplied by Browsix rather than a Linux source tree.
Standard system interface WASICore Wasm modules or components call standards-track interfaces implemented by a compatible runtime.The host runtime services only the capabilities explicitly granted to the module or component.Portable, composable, capability-based execution across browsers, cloud, and embedded systems; it is not a Linux ABI or kernel.
Extended WASI interface WASIXPrograms compile against WASI plus extensions for threads, sockets, TTYs, fork, exec, and related POSIX facilities.The supporting runtime implements the extended WASIX calls and their process and I/O behavior.Expands the POSIX-shaped surface without a full guest machine; semantics remain the runtime’s interface rather than Linux kernel code.
Node-oriented runtime WebContainersNode.js applications, package managers, and operating-system-like commands run inside a browser tab.The WebContainers runtime supplies the filesystem, processes, networking bridges, and Node-facing environment.Deeply optimized for Node toolchains and interactive web development; it does not expose the general Linux ABI.

For the design rationale behind these boundaries, read Why we compiled real Linux to WebAssembly → For a related Linux-hosted interface-first design, see WALI.


Boot to program

A Linux machine in five boundaries.

The browser never impersonates a POSIX userspace. It instantiates a kernel, delivers a boot contract, and services explicit hardware-facing imports.

01 / LOADHardwareJSPreflights and compiles the kernel module
02 / BOOTboot_info v3Memory map, CPUs, timer, initrd, entropy
03 / KERNELvmlinux.wasmLinux initializes its wasm32 architecture
04 / PROCESSUser WorkerOne address space, shared user memory
05 / I/OLinux driversVirtqueues cross into browser backends

Non-negotiable invariants

What this system is—and is not.

These boundaries are architectural, not marketing shorthand. They are enforced by the build, the runtime, and executable gate suites.

INV-01

Linux owns Linux

VFS, scheduling, signals, networking, terminals, permissions, and process semantics remain inside the kernel. Unsupported hardware gets a wasm32 driver.

INV-02

One kernel memory

Current vmlinux.wasm imports one shared env.kernel_memory. User address spaces live in separate shared memories owned by process Workers.

INV-03

Workers are CPUs

The dedicated kernel Worker is CPU 0. Pool Workers are virtual CPUs and host process address spaces; work is cooperative and explicitly parked.

INV-04

Blocking does not spin

Compiler-native continuations allow a blocking syscall path to park and later resume, without rewinding the C stack or relying on JavaScript stack switching.

INV-05

Contracts fail loudly

ABI versions, memory limits, parked-frame witnesses, ring state, and plugin provenance are validated before work proceeds.

INV-06

Source is authoritative

This publication tracks the checked-out Linux, HardwareJS, and hwjs-cc revisions. Historical designs are called out instead of being presented as current behavior.


The seam

Inspect every cross-layer contract.

Boot records, shared memories, syscall traps, user-copy leaves, suspension tokens, virtqueues, and signal rings are cataloged in one place.

Open the contract reference →