Browsix - Bringing Unix to the Browser
For more details, check out our tech report (PDF).
Another way to think about this is that modern web applications are multi-process by nature - the client and some of the application logic lives in the browser, and some of it lives in the cloud, often implemented as microservices.
Browsix lets you rethink the boundary between code executing in the browser vs. server-side, while taking advantage of the multi-core nature of modern computing devices.
Browsix enables you to compose the in-browser part of your web applications out of processes. Processes behave as you would expect coming from Unix: they run in parallel with the main browser thread, can communicate over pipes, sockets, or the filesystem, and can create subprocesses. This process model is implemented on top of existing browser APIs, like web workers, so it works in all modern browsers. Browsix applications can be served statically or over a CDN.
The Browsix Shell
As a proof of concept, we've implemented a POSIX-like shell on top of
Browsix, along with an implementation of a number of standard Unix
sha1sum, and friends). The
utilities are all standard node programs that will run directly under
node, or in the browser under Browsix. Individual commands are
executed in their own workers, and piping works as expected:
Try it out here: live demo!
Browsix currently supports running node.js, Go, and C/C++ programs. It supports Go with a modified GopherJS compiler (requires a host Go 1.6 install for now), and C/C++ with modifications to Emscripten.
There are two parts to Browsix: build tooling (the modified Go + C compilers) and runtime support (the kernel + Browsix APIs).
Get browsix through npm:
$ npm install --save browsix
Building & Testing
Browsix requires nodejs 4.3.0 or later, which is more recent than the version packaged in Ubuntu Wiley. To get a recent version of node, follow the instructions on the node.js website. If you don't know whether you should choose node 4.x or 5.x, choose 4.x (it is the long-term support branch).
Browsix has three other dependencies:
npm (usually installed
along with node), and
make, and builds on OSX and Linux systems.
Once you have those dependencies:
$ git clone --recursive https://github.com/plasma-umass/browsix $ cd browsix $ make test-once serve
This will pull the dependencies, build the runtime and all the utilities, run a number of tests in either Firefox or Chrome, and then launch a copy of the shell served locally.
$ ./docker/build.sh .... root@3695ed0cdf45:~/browsix# make test-once serve TEST [13:07:00] Using gulpfile ~/browsix/gulpfile.js [13:07:00] Starting 'copy-node-kernel'... [13:07:00] Starting 'copy-node'... [13:07:00] Starting 'lint-kernel'... [13:07:00] Starting 'lint-browser-node'... [13:07:00] Starting 'lint-bin'... [13:07:00] Starting 'lint-syscall-api'... [13:07:00] Finished 'copy-node-kernel' after 82 ms [13:07:02] Finished 'lint-syscall-api' after 1.61 s [13:07:04] Finished 'lint-kernel' after 3.72 s [13:07:05] Finished 'lint-browser-node' after 4.46 s [13:07:05] Finished 'lint-bin' after 5.08 s [13:07:05] Starting 'build-bin'... [13:07:06] Finished 'copy-node' after 5.16 s [13:07:06] Starting 'build-kernel'... [13:07:06] Starting 'build-browser-node'... ...
In-browser node limitations
browser-node implementation has an important to understand
limitation: you must explicitly call
this, utilities will work under real-node, but appear to hang under
browser-node. This is not an intrinsic limitation, but it is a
hairy implementation detail -- node exits when the event loop is
empty, and there are no active timers or network callbacks. For us to
do the same thing means we need to hook
setTimeout and any other
functions that take callbacks to ensure we don't exit early.
For a high-level overview of the system design and architecture, please see this document.
You're interested in contributing? That's great!
The process is similar to other open-source projects hosted on github:
- Fork the repository
- Make some changes
- Commit your changes with a descriptive commit message
- Open a pull request
If you have questions or problems, please open an issue on this repository (plasma-umass/browsix).
This project is licensed under the MIT license, but also incorporates code from other sources.