Introducing jswasi - a Wasm/WASI runtime for browsers
Published:
Topics: Open software libraries, Open source tools
WebAssembly (Wasm), introduced in 2017, is a binary format designed as a portable compilation target aiming to execute at near-native speeds. With the addition of built-in Wasm virtual machines (VMs) in browsers, it has enabled the use of a wide range of non-JavaScript programs in a client-side environment. Through Wasm, browsers gain interoperability with large pre-existing codebases and toolkits written in e.g. C/C++, C#, Go, Python and Rust.
Wasm is run within a sandboxed environment, with applications only able to exit the sandbox through the use of an appropriate API. The WebAssembly System Interface (WASI) API helps mitigate this deficiency by offering many familiar operating-system-like feature APIs.
While many great individual applications like ffmpeg have been enabled to run in the browser through Wasm and the WASI API, an especially interesting capability enabled by the developments in this space is the potential to emulate a full “multi-program console” experience, entirely client-side. This is what Antmicro’s newly released jswasi project, a Wasm runtime that can be expanded with complete applications which are served or embedded by providing a root filesystem with wasm32-wasi executables, aims to enable.
Using WebAssembly to build a Linux-like environment in your browser
In order for jswasi to become reality, we combined multiple web APIs that control web browser and host device functionality, the core WASI API as well as our own WASI extensions library to support new functionalities such as process management, signal handling and character devices, all of which were vital for creating a Linux-like command line experience in the browser.
The initial version of jswasi was created for Chrome which pioneered the relevant functionalities such as filesystem API, but ultimately it was always meant to be portable. By the time of jswasi’s open source release, the continuing convergence of browsers in terms of functionality and standards has in fact enabled this goal. Today, jswasi works on Chrome and its derivatives, Firefox, as well as on their mobile variants.
It can be also hosted on your own website with minimum requirements, as all code is executed on the user’s local machine and does not require any backend or additional server resources.
Using the wash shell to explore jswasi
As part of the efforts to make jswasi practically useful and easy to test and demonstrate, we developed our own Linux-like shell, wash, since other existing shells such as Bash or zsh required additional dependencies that were not available at the time in the WASI software architecture. In comparison, wash only requires a minimal set of dependencies, which was vital in the process of working around the limitations of browsers. You can try a demo of wash here.
While the shell offers a familiar user interface, the underlying runtime in fact provides a lot of commonly used system calls, and by implementing these we are able to run a lot of binaries that couldn’t normally be run through the ordinary WASI API.
As one of our goals was for jswasi to function as a development environment, we implemented the ability to edit files from within the runtime, by choosing two lightweight text editors written in Rust and subsequently porting them into jswasi. These editors were chosen for the fact that they require a minimal amount of dependencies: to make them work, we only had to implement the poll_oneoff system call along with termios. The more advanced variant, Ox editor, combines popular concepts from other editors likeVim, Nano, and Kiro - such as having intuitive and logical key bindings together with support for customization and extensibility according to the needs of the user. The other, Kibi, is intentionally limited to 1024 lines of code, while providing incremental search, syntax highlighting, line numbers and more, and is an interesting programming experiment in its own right.
Ox editor, running in jswasi and wash, is demonstrated below.
Accessing physical and virtual filesystems with full access to the browser and more
In order to connect the WASI API to the user’s own local environment and to ensure that the browser no longer operates in isolation from the device that it runs on, it was essential to implement the ability to use both physical and virtual local file systems. The browser is capable of working with files within a virtual drive, while full read/write access to local drives is provided through a simple mount command, as shown below.
Filesystem access turns jswasi into a software and hardware development environment without requiring the installation of applications on the local computer. Currently, jswasi primarily focuses on a command line experience, but in the future, we aim to enable graphical applications, i.e. introduce framebuffer support alongside other improvements.
Incorporating jswasi into other web-facing applications
With our work on jswasi, we expanded the possibility of running a wide range of applications from within the browser. Text editing and file access is only the beginning of our work with jswasi, as we intend to incorporate its functionality into future projects that will harness Wasm and WASI by blurring the distinction between the browser and the local machine, as well as enable customers to create new workflows and programming environments on top of it.