1# WASI: WebAssembly System Interface 2 3WebAssembly System Interface, or WASI, is a new family of API's being 4designed by the [Wasmtime] project to propose as a standard engine-independent 5non-Web system-oriented API for WebAssembly. Initially, the focus is on 6WASI Core, an API module that covers files, networking, and a few other 7things. Additional modules are expected to be added in the future. 8 9WebAssembly is designed to run well on the Web, however it's 10[not limited to the Web](https://github.com/WebAssembly/design/blob/master/NonWeb.md). 11The core WebAssembly language is independent of its surrounding 12environment, and WebAssembly interacts with the outside world 13exclusively through APIs. On the Web, it naturally uses the 14existing Web APIs provided by browsers. However outside of 15browsers, there's currently no standard set of APIs that 16WebAssembly programs can be written to. This makes it difficult to 17create truly portable non-Web WebAssembly programs. 18 19WASI is an initiative to fill this gap, with a clean set of APIs 20which can be implemented on multiple platforms by multiple engines, 21and which don't depend on browser functionality (although they 22still can run in browsers; see below). 23 24## Capability-Oriented 25 26The design follows 27[CloudABI](https://github.com/NuxiNL/cloudlibc)'s 28(and in turn 29[Capsicum](https://www.cl.cam.ac.uk/research/security/capsicum/))'s concept of 30[capability-based security](https://en.wikipedia.org/wiki/Capability-based_security), 31which fits well into WebAssembly's sandbox model. Files, 32directories, network sockets, and other resources are identified 33by UNIX-like file descriptors, which are indices into external 34tables whose elements represent capabilities. Similar to how core 35WebAssembly provides no ability to access the outside world without 36calling imported functions, WASI APIs provide no ability to access 37the outside world without an associated capability. 38 39For example, instead of a typical 40[open](http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html) 41system call, WASI provides an 42[openat](https://linux.die.net/man/2/openat)-like 43system call, requiring the calling process to have a file 44descriptor for a directory that contains the file, representing the 45capability to open files within that directory. (These ideas are 46common in capability-based systems.) 47 48However, the WASI libc implementation still does provide an 49implementation of open, by taking the approach of 50[libpreopen](https://github.com/musec/libpreopen). 51Programs may be granted capabilities for directories on launch, and 52the library maintains a mapping from their filesystem path to the 53file descriptor indices representing the associated capabilities. 54When a program calls open, they look up the file name in the map, 55and automatically supply the appropriate directory capability. It 56also means WASI doesn't require the use of CloudABI's `program_main` 57construct. This eases porting of existing applications without 58compromising the underlying capability model. See the diagram below 59for how libpreopen fits into the overall software architecture. 60 61WASI also automatically provides file descriptors for standard 62input and output, and WASI libc provides a normal `printf`. In 63general, WASI is aiming to support a fairly full-featured libc 64implementation, with the current implementation work being based on 65[musl](http://www.musl-libc.org/). 66 67## Portable System Interface for WebAssembly 68 69WASI is being designed from the ground up for WebAssembly, with 70sandboxing, portability, and API tidiness in mind, making natural 71use of WebAssembly features such as i64, import functions with 72descriptive names and typed arguments, and aiming to avoid being 73tied to a particular implementation. 74 75We'll often call functions in these APIs "syscalls", because they 76serve an analogous purpose to system calls in native executables. 77However, they're just functions that are provided by the 78surrounding environment that can do I/O on behalf of the program. 79 80WASI is starting with a basic POSIX-like set of syscall functions, 81though adapted to suit the needs of WebAssembly, such as in 82excluding functions such as fork and exec which aren't easily 83implementable in some of the places people want to run WebAssembly, 84and such as in adopting a capabilities-oriented design. 85 86And, as WebAssembly grows support for 87[host bindings](https://github.com/webassembly/host-bindings) 88and related features, capabilities can evolve to being represented 89as opaque, unforgeable 90[reference typed values](https://github.com/WebAssembly/reference-types), 91which can allow for finer-grained control over capabilities, and 92make the API more accessible beyond the C-like languages that 93POSIX-style APIs are typically aimed at. 94 95## WASI Software Architecture 96 97To facilitate use of the WASI API, a libc 98implementation called WASI libc is being developed, which presents 99a relatively normal musl-based libc interface, implemented on top 100of a libpreopen-like layer and a system call wrapper layer (derived 101from the "bottom half" of 102[cloudlibc](https://github.com/NuxiNL/cloudlibc)). 103The system call wrapper layer makes calls to the actual WASI 104implementation, which may map these calls to whatever the 105surrounding environment provides, whether it's native OS resources, 106JS runtime resources, or something else entirely. 107 108[This libc is part of a "sysroot"](https://github.com/WebAssembly/reference-sysroot), 109which is a directory containing compiled libraries and C/C++ header 110files providing standard library and related facilities laid out in 111a standard way to allow compilers to use it directly. 112 113With the [LLVM 8.0](http://llvm.org/) 114release, the WebAssembly backend is now officially stable, but LLVM 115itself doesn't provide a libc - a standard C library, which you 116need to build anything with clang. This is what the WASI-enabled 117sysroot provides, so the combination of clang in LLVM 8.0 and the 118new WASI-enabled sysroot provides usable Rust and C compilation 119environments that can produce wasm modules that can be run in 120[Wasmtime] with WASI support, in browsers with the WASI polyfill, 121and in the future other engines as well. 122 123 124 125## Future Evolution 126 127The first version of WASI is relatively simple, small, and 128POSIX-like in order to make it easy for implementers to prototype 129it and port existing code to it, making it a good way to start 130building momentum and allow us to start getting feedback based on 131experience. 132 133Future versions will change based on experience 134and feedback with the first version, and add features to address 135new use cases. They may also see significant architectural 136changes. One possibility is that this API could 137evolve into something like 138[Fuchsia](https://en.wikipedia.org/wiki/Google_Fuchsia)'s 139low-level APIs, which are more complex and abstract, though also 140more capable. 141 142We also expect that whatever WASI evolves into in the future, it 143should be possible to implement this initial API as a library 144on top. 145 146## Can WASI apps run on the Web? 147 148Yes! We have a polyfill which implements WASI and runs in browsers. 149At the WebAssembly level, WASI is just a set of callable functions that 150can be imported by a .wasm module, and these imports can be implemented 151in a variety of ways, including by a JavaScript polyfill library running 152within browsers. 153 154And in the future, it's possible that 155[builtin modules](https://github.com/tc39/ecma262/issues/395) 156could take these ideas even further allowing easier and tighter 157integration between .wasm modules importing WASI and the Web. 158 159## Work in Progress 160 161WASI is currently experimental. Feedback is welcome! 162 163[Wasmtime]: https://github.com/bytecodealliance/wasmtime 164