Programs written to run on conventional operating systems typically depend on OS abstractions like processes, pipes, signals, sockets, and a shared file system. Compiling programs into JavaScript, asm.js, or WebAssembly with tools like Emscripten or GopherJS isn't enough to successfully run many programs client-side, as browsers present a non-traditional runtime environment that lacks OS functionality. Porting these applications to the web currently requires extensive rewriting or paying to host significant portions of code in the cloud.
Browsix is our answer to these challenges, featuring:
Unmodified C, C++, Go, and Node.js programs run as processes on Web Workers, executing in-parallel with the main browser thread – no need to worry about long-running computations blocking event-handling or page rendering.
By working at the lowest levels of abstraction, Browsix provides shared resources to multiple language runtimes, just as traditional operating systems enable running programs written in a host of languages.
By enabling a large class of programs (including legacy codebases) to run in-browser, Browsix can free you from the chore of sandboxing and load-balancing programs server-side.
A Unix terminal exposing the dash POSIX shell lets developers compose functionality and inspect Browsix state in a familiar way. (view source)
In-browser editor that runs pdflatex and bibtex to generate PDFs. Required < 150 LoC to orchestrate these applications. (view source)
Client/server web application written in JavaScript and Go. The Go server blits text over images using off-the-shelf libraries and runs unmodified under Browsix. 30 LoC policy in client chooses to route requests to cloud or to in-browser server process. (view source)
Browsix is a framework that bridges the considerable gap between conventional operating systems and the browser, enabling unmodified programs expecting a Unix-like environment to run directly in the browser. Browsix does this by mapping low-level Unix primitives, like processes and system calls, onto existing browser APIs, like Web Workers and postMessage.
Browsix brings all of these abstractions into unmodified browsers, and is isolated and secured to the same extent any normal web page is: at the level of the browser tab.
To use Browsix, client-side JavaScript code creates an instance of a Browsix kernel (which involves telling it how to initialize the filesystem), and then asks the kernel to start or kill processes. Users can also perform HTTP requests to a given Browsix TCP port, and register callbacks a number of events, like when a process has written to standard out or standard error, for when processes exit, and for when ports are ready.
Processes are built on top of Web Workers, letting
applications run in parallel and spawn
subprocesses. System calls include fork
, spawn
, exec
, and
wait
.
Signals with kill(2)
and signal handlers.
Shared Filesystem accessible from multiple processes.
Pipes are supported with pipe(2)
enabling developers to compose processes into pipelines.
Sockets include support for TCP socket servers and clients, making it possible to run applications like databases and HTTP servers together with their clients in the browser.
Thanks to a successful Summer of Code project, Browsix has an init system that supports managing and supervising in-browser services specified by systemd unit files.
Browsix is described in a peer-reviewed paper from the ASPLOS 2017 conference.
Check out the paper on the ACM Digital Library, or alternatively here.
Browsix comprises two core parts:
A kernel written in TypeScript that makes core Unix features (including pipes, concurrent processes, signals, sockets, and a shared file system) available to web applications.
Extended JavaScript runtimes for C, C++, Go, and Node.js that support running programs written in these languages as processes in the browser.
We will soon have more push-button instructions for integrating Browsix into your project. For now, check out GitHub for more details.