Wasm Labs

WebAssembly Language Runtimes March update: new languages and slim builds

By Jesús González
At 2023 / 03 5 mins reading

This March in the WebAssembly Language Runtimes project (WLR) we have new binary releases for the latest supported versions of PHP, Python and Ruby. These are ready-to-run Wasm modules for popular interpreted languages.

We ported several common libraries to WASI and bundled them with the latest language runtime releases. We now also offer different flavors of the language runtimes so you can choose what fits your needs best considering size and functionality.

Building common libraries to WASI

Language runtimes provide extended functionality by leveraging common public libraries. For example, we were already building sqlite3 into our PHP and Python Wasm releases to allow access to SQLite databases. Popular applications often require additional extensions on top of the basic language runtime. For example, Drupal uses libpng (via the libpng PHP extension) for image manipulation.

This month we have worked to port libicu, libpng, libuuid, libxml2, liboniguruma, zlib to WASI and build them internally into PHP and some of them into Python (where we were previously relying on binaries from the singlestore-labs/python-wasi repository).

We are working on providing these and more common public libraries as WASI-compatible static libs, which advanced users can reuse and integrate into their own projects.

Approaches for standard libraries

Having the interpreter built for WebAssembly+WASI is just a first step.

Most interpreted languages come with a standard library written in that programming language. There are no specific rules around how to distribute these libraries when targeting Wasm. While they can be provided separately from the interpreter, it is convenient to have everything bundled together. Otherwise, it is up to the user to pre-open and provide the standard library when starting the language runtime.

We decided on offering two bundling approaches - container images and all-in-one standalone WebAssembly binaries.

Container Images

Docker is working on integrating WebAssembly in their Desktop product. As part of that integration, they have added support to run Wasm applications with docker run.

You can also run WASI workloads on Kubernetes via crun.

Both of these rely on distributing the WebAssembly binary within a container image.

We have updated our Python OCI packages to include two runtime flavors (with Python's standard library included):

  • Default: it can run on any WASI-compliant containerd runtime (e.g. wasmtime)

    ghcr.io/vmware-labs/python-wasm:3.11.1
  • WasmEdge: it can run on the wasmedge containerd runtime (WasmEdge supports additional socket APIs)

    ghcr.io/vmware-labs/python-wasm:3.11.1-wasmedge

Standalone WebAssembly Binaries

We are also providing WebAssembly binaries that bundle the interpreter and the standard libraries in a single file. We do so by using a virtual file system (VFS). The rest of this section explains the technical details of how this works.

The Ruby project has great WebAssembly+WASI support. This has been driven by Yuta Saito and his hard work has made this possible. Saito-san is also the creator of the ruby.wasm project.

We are not using ruby.wasm sources or binaries, but our work is deeply inspired by it.

As part of the work on ruby.wasm Saito-san also created wasi-vfs. This project implements a virtual filesystem for applications built for the wasm32-wasi target, on top of wasi-libc. It is agnostic of programming language and host specifics.

wasi-vfs takes advantage of the wizer project, which is a WebAssembly pre-initializer from the Bytecode Alliance. We plan to explore in depth wasi-vfs and wizer in a future blog post. For now, it is sufficient to say that it can pack the standard library of the language interpreter along with the interpreter itself within the same WebAssembly binary. The filesystem gets 'mounted' at runtime and is accessed transparently by the interpreter.

This is what we used in the latest Ruby and Python releases.

We are currently working on making it easier to create customized bundles that include your own application together with the language interpreter and just the libraries and extensions that are needed.

New language runtime flavors

We are now offering two build flavors for Ruby and PHP: standard and slim. The standard build includes common extensions and libraries for a 'Batteries Included' experience. This means a larger file size but also that applications requiring those dependencies will work out of the box. We plan on significantly expanding the number of supported libraries over time. Slim builds include just the interpreter and the minimal amount of libraries it needs to work. Slim builds are tiny (the PHP WASI build is just 5.4MiB) and are ideal for scenarios where size and startup speed are important, such as certain serverless applications performing simple logic operations.

Our current Python release uses just the bare minimum of libraries so we still don't have a slim and standard versions.

Latest releases

Conclusions

Our main drive with these changes is to make the WLR releases easier to use and helpful in more ways. Building and integrating more common libraries expands the possible use cases for the language runtimes, while providing different flavors gives people more varied deployment options.

A great way of getting started with WLR is with our Wasm serverless project Wasm Workers Server.

We'd love to hear from you! Let us know how you are using these language runtimes and how we can make them better for your use case. You can find us on Twitter and in our GitHub repository ⭐️.

Do you want to stay up to date with WebAssembly and our projects?