Igalia Compilers Team

Est. 2011

Five years of JavaScript on WebAssembly

This is a cross-post from my personal blog Five years of JavaScript on WebAssembly.

This post summarizes my talk at Wasm I/O 2026: Five Years of JavaScript on WebAssembly. The recording will be uploaded to the 2026 playlist.

By the end, you should have a clear picture of how JavaScript on WebAssembly evolved from an experiment into a production toolchain, the design decisions that shaped it, and where I think it's heading next.

The talk is structured into 5 main sections, each representing a key event during the past 5 years (2021 - 2026) of development of JavaScript on WebAssembly and Javy, which is the leading character of the talk.

April 23rd 2021 — Inception #

Javy's git log shows that on April 23rd 2021 I made the first commit:

Author: Saúl Cabrera 
Date: Fri Apr 23 09:41:56 2021 -0400

First commit. Several important things to note:

A fair and usually common question that gets asked is why do you need to run JavaScript on WebAssembly? Isn't WebAssembly meant to run in the browser and alongside JavaScript? It all depends on the use-case. WebAssembly's inherent secure-by-default and near native performance properties are very appealing for use-cases that involve executing untrusted code server side.

Thus, in 2021 I had set myself the objective of creating a toolchain to make it extremely easy and accessible to target WebAssembly. Additionally, the toolchain should also:

  1. Produce the smallest possible WebAssembly modules, to minimize the operational infrastructure cost of managing the native binaries produced by compiling Wasm to machine code and to be competitive with other WebAssembly toolchains.

  2. Offer reasonably complete JavaScript spec support.

  3. Offer decent runtime performance.

QuickJS is a natural fit for all three goals, and has powered Javy ever since.

2022 — Production ready toolchain #

During 2022 Javy became production ready: it was put in the hands of developers and started serving real production use-cases.

The first production ready version included an extremely simple interface for building WebAssembly modules:

javy build index.js -o index.wasm

And it also included a feature to generate extremely small WebAssembly modules, in the range of 1kb - 16kb. During Wasm I/O 2023, Jeff Charles presented the underlying technical details that make this possible.

2023 — Governance model #

2023 brought no major technical milestones, but an equally important shift happened: Javy moved to a hosted-project model under the Bytecode Alliance.

While Javy was initially designed for a specific use-case, it eventually found its way into multiple companies operating in the WebAssembly space. This adoption prompted us to rethink its governance model, shifting towards an open, community-driven model that ensures a healthy environment for the project's growth and development.

2024 — A profiler for JavaScript on WebAssembly #

During 2024, we set out to solve the problem of profiling JavaScript programs on WebAssembly. It is critical for developers to understand how their programs behave inside WebAssembly in order to perform optimizations where applicable. This post intentionally skips over all the technical details behind the research and implementation work; however, if you're interested in reading further, you can check out the first post of my series, A profiler for JavaScript on WebAssembly, Part 1, which accompanies the work happening upstream to materialize this research. The series is not complete, but the first part lays the foundation for why this is important and the challenges behind it.

2025 — Toolchain extensibility #

Javy's design philosophy was always to provide a minimal and lightweight JavaScript on Wasm implementation by default, allowing for extensibility where appropriate. The very initial version of an extensible runtime required users to assemble their own runtime from a set of official Rust crates. This approach was not ergonomic and required a non-trivial knowledge of Javy's internals to get right.

During 2025, we overhauled the extensibility story, making the Javy CLI the canonical starting point of extensibility, promoting the CLI from a simple entry point for the basic use-case into a build tool capable of orchestrating JavaScript-on-WebAssembly builds for third-party use cases.

The official RFC behind this work contains all the technical details.

2026 — A preliminary look at potential throughput improvements #

WebAssembly, as a Harvard Architecture, does not allow just-in-time code generation yet. Thus, any dynamic language running on WebAssembly which requires just-in-time generation as a means to improve throughput is limited to interpreter mode only. This is the case for Javy today: it principally relies on QuickJS' interpreter for code execution. Even though QuickJS' interpreter is very well optimized, there is still room for improvement. Profiles, taken from the work done in 2024 and being upstreamed this year, show that optimizing for:

has the potential to considerably improve throughput. More concretely, a recent proof-of-concept of compiling QuickJS bytecode to Wasm, conducted during late 2025, showed that optimizing function calls can improve performance by ~1.2x over the interpreter, and optimizing closure creation, particularly by relying on the Wasm GC proposal, can improve performance by ~1.5x-~3.5x over the interpreter. Note that this work is in its very early days, and the benchmarks were conducted on a very small sample of programs. Our plan is to upstream the compiler as an experimental feature during the upcoming 6-12 months.

Au revoir #

What started in 2021 as — "can we make JavaScript on WebAssembly easy?" — has turned into a question we now get to answer in more interesting ways: not just easy, but small, fast, extensible, and soon, possibly, faster.