Annual Report

Welcome to the annual State of WebAssembly (Wasm) article, where I’ll recap the events of 2025 and preview what 2026 could bring to this rapidly evolving technology.

As we enter 2026, it’s a good time to reflect on the significant progress made over the past year and look ahead at what’s on the horizon.

Browser Coverage Note

When I mention browser support for different WebAssembly features, I typically focus on Chrome, Firefox, and Safari. I don't mention Edge or Opera because they're built using the same Chromium open-source project as Chrome. It's still a good idea to test your modules in these browsers, but they usually inherit the WebAssembly work done for Chrome.

To verify feature support (including non-browser runtimes), check the official WebAssembly feature list. If your browser supports the feature, there will be a checkmark in the ‘Your browser’ column to the right of the feature’s name.

Last year’s State of WebAssembly.

Now, let’s dig in.

2025 in Review

When using WebAssembly in the browser, most teams want cross-browser support or at least a solid fallback, before adopting a new feature. Because Safari still represents a large share of web traffic, its Wasm support often determines when a feature is viable in production. In 2025, the Safari team continued closing key gaps.

Safari

Two Safari additions in 2025 helped complete cross-browser support for important Wasm proposals:

Exception Handling (exnref) — Safari 18.4

  • There was already an Exception Handling proposal live in all browsers. The original proposal was adjusted to include a new ‘exnref’ value to address a number of issues with the existing approach that included difficulty for the JavaScript API to handle the identity of thrown exceptions. The exnref value also allows for a reduction in the complexity of both the specification and engine implementations.

    Because exception handling was already live in all browsers, the original approach will continue to work until it’s determined that it’s safe to be removed.

JavaScript String Builtins arrived in version 26.2.

  • This feature wraps the JavaScript String primitive so that there’s no need for glue code when calling functions like ‘compare’ or ‘concat’. This simplifies modules and improves performance. You can find more information about string builtins here

    Glue code is simply JavaScript code written by a developer, provided by a framework, or generated by a compiler toolchain to act as a go-between when the module’s code can’t do something independently. When the JavaScript code is called, it does some work on the module’s behalf.

    The JavaScript String Builtin feature is a first step towards a larger goal of allowing the use of other builtin objects and primitives from a WebAssembly module without the need for JavaScript glue code

In addition, Safari shipped several Wasm runtime improvements in 2025:

In addition to the features just mentioned, Safari also received the following WebAssembly improvements:

  • Support for JIT-less Wasm was added so that modules will still work if Just-In-Time compilation is disabled
  • Large WebAssembly modules now run faster thanks to a new in-place interpreter being used to evaluate modules first
  • The following methods have been added to the WebAssembly JavaScript API allowing for the conversion of a module’s memory between fixed-length and resizable buffers:
  • WebAssembly.Memory.prototype.toResizableBuffer()
  • WebAssembly.Memory.prototype.toFixedLengthBuffer()

Standardized Features

Over this past year, the following features have reached phase 5 (completed standardization) and are now considered “done” at the specification level:

  • Exception Handling with exnref
  • JavaScript String Builtins
  • Memory64

The linear memory of a WebAssembly module was originally limited to a maximum of 4 GB due to the use of 32-bit indexes. Because some applications need more than 4 GB of memory, 64-bit indexes have been added.

There are some proposals in the works that may help improve things but, at the moment, there are a couple things to be aware of with this feature before you jump in:

  • Even though a 64-bit pointer can theoretically access up to 16 exabytes of memory, web browsers currently limit memory to a maximum of 16 GB.
  • Browser engines were able to make some optimizations around 32-bit pointers that they’re not able to do with 64-bit pointers. Without those optimizations, unfortunately, there is a potentially large performance hit depending on the workload. The following article goes into detail about the performance penalty when using 64-bit mode.

For now, the recommendation is that you should only use Memory64 if you need more than 4 GB of memory.

Progress of Other Features

Beyond the features that completed standardization, several other proposals made meaningful progress in 2025 with some shipping broadly while others are still gated behind a flag.

Note on “behind a flag”

When a feature is “behind a flag,” it only works if a user/developer turns on an experimental setting (usually for pre-release testing). Flags can change browser behavior, and the underlying implementations may be rough or expose security gaps. Use with caution.

Relaxed SIMD

When SIMD (Single Instruction, Multiple Data) was proposed for WebAssembly, 128-bit fixed-width SIMD was chosen as a starting point because it was seen as having the most hardware support.

SIMD is a type of parallel processing that takes advantage of a CPU’s SIMD instructions to perform the same operation on multiple points of data simultaneously. This can result in large performance gains for things like image processing.

There are additional SIMD instructions that are possible depending on the hardware so the Relaxed SIMD proposal’s aim is to take advantage of some of those additional instructions. If you’d like to learn more about Relaxed SIMD, the proposal can be found here.  

This proposal was standardized in 2024 but was still behind a flag in Firefox and Safari by the end of the year. In 2025, this feature came out from behind a flag in Firefox but is still behind a flag in Safari.

JavaScript Promise Integration (JSPI)

This feature’s aim is to allow a Wasm module’s synchronous code to make asynchronous Web API calls. When this happens, the browser would pause the module’s execution while it waits for the call to complete. More information on this proposal can be found here. 

This proposal is now at phase 4 and is live in Chrome. It’s still behind a flag in Firefox.

Safari hasn’t publicly committed to if they’re working on this feature. They did have some concerns about the proposal and didn’t initially want to implement it. That changed late in 2025 when they removed their objection so that’s a promising development.

If you want to use this feature before it arrives in Safari, one approach that’s possible is to use feature detection for JSPI and fall back to the slower Asyncify approach if JSPI isn’t available.

WebAssembly CSP

CSP (Content Security Policy) is a security mechanism used by web developers to specify what resources are allowed to be loaded by the browser for their website. When a CSP is used, the browser will block the download of files, or execution of code, that are not included in the allow lists.

WebAssembly CSP extends CSP limitations to WebAssembly modules. Using the ‘wasm-unsafe-eval’ keyword in the ‘script-src’ directive explicitly allows the loading, compilation, and instantiation of WebAssembly modules. The proposal is here if you’d like to read more about it: 

Because wasm-unsafe-eval is supported across all major browsers, this work has advanced and is being standardized.

Wide Arithmetic

For Wasm code to perform 128-bit integer operations, it needs to use 64-bit instructions, or external library calls, but this is currently 2 to 7 times slower than native performance. This proposal’s aim is to add new instructions to improve the performance of 128-bit arithmetic operations.

During 2025, this proposal moved to phase 3 and is now being implemented in runtimes.

Stack Switching

The goal of this proposal is to allow a WebAssembly module to manage multiple execution stacks concurrently by using continuations. A continuation represents a snapshot of execution on a particular stack that could be suspended or resumed. Language providers would use these continuations to build the non-local control flow features that they need like async/await, coroutines, or generators/iterators to name a few. A more detailed explanation can be found here if you’d like to learn more: 

This proposal also moved to phase 3 this past year.

There are also a number of interesting proposals in phases 1 and 2 but they’re still early in the discussion and planning stages so I won’t mention them here. If you’d like to see what they are, the list of all proposals can be found here

WebAssembly 3.0

WebAssembly 3.0 is a specification milestone: it’s a clear line in the sand for “modern Wasm support,” bundling a growing set of standardized features under one version label.

When WebAssembly was launched as an MVP in 2017, it was considered 1.0.

In 2022, a version 2.0 of the WebAssembly specification was started as a way of saying that, if a runtime supports WebAssembly 2.0, it supports all of the standardized features that are a part of it.

This past year, WebAssembly reached another milestone when 3.0 was announced. All standardized features since 2.0, including the following, are now considered part of 3.0:

  • Custom Text Format Annotations
  • Deterministic profile
  • Exception Handling
  • Garbage Collection
  • JavaScript String builtins
  • Memory64
  • Multiple Memories
  • Relaxed SIMD
  • Tail Calls
  • Typed References

 

Many of these 3.0 features are already shipping in the major web browsers and in some of the stand-alone runtimes. If you’d like to investigate the status of a feature for your target runtimes, you can use the following website.

If you’d like to learn more about the list of features in 3.0, details can be found here.

Outside the Browser

Kotlin

Kotlin is a cross-platform high-level programming language that’s designed to be a modern alternative to Java but is fully interoperable with the Java ecosystem. 

Because it’s multiplatform, it can compile to Java bytecode for the JVM (Java Virtual Machine), JavaScript, and native machine code.

With the 2.2.20 release in September of 2025, a beta version of the Kotlin/Wasm tool is now available that allows Kotlin code to be compiled to WebAssembly. 

.NET

.NET 10 was released in November of 2025 and comes with a lot of performance and reliability improvements. It also includes better diagnostic collecting either through C# code, via the JavaScript interop, or by using the browser’s built-in developer tools.

In 2025, we saw the continued innovation that we’ve come to expect from The Uno Platform. In addition, with every release the Uno Platform’s performance has improved:

  • With their 5.6 release in early 2025, they were able to improve ahead-of-time (AOT) compilation that resulted in 2.5 times faster execution for most scenarios and up to 10 times faster execution in certain cases.
  • With their 6.3 release in October, they made significant improvements around image decoding allowing for faster load times and smoother UIs in apps that have heavy image workloads.
  • Uno Platform’s latest release in November continues this trend by taking advantage of the performance and reliability improvements in .NET 10.

Aside from the performance improvements brought by both .NET and the Uno Platform, 2025 saw the announcement of a closer collaboration between the two organizations. With .NET being open source, the Uno Platform has been helping with .NET improvements for some time now but this makes things more official. From the WebAssembly side of things, this collaboration means a focus on something that many .NET developers have been asking for: multithreading.

WebAssembly System Interface (WASI)

WASI is a standardization effort led by the Bytecode Alliance for WebAssembly’s use outside the browser to ensure things are done in a secure and consistent way. It also includes the creation of a set of interfaces that your modules can access called worlds. For example, there’s a ‘wasi-http’ set of interfaces that your module can use to send and receive HTTP requests.

WASI also leverages the Component Model Wasm feature for the linking of multiple modules that are potentially written in different languages. The Component Model is also how modules interface with the WASI worlds.

The WASI work is being released in phases and advanced to 0.2 early in 2024. Work then started towards 0.3 by adding native async support to the Component Model and adjustmenting the WASI worlds to take advantage of the new async capabilities. 

Although WASI 0.3 is not quite ready, the Wasmtime runtime now has experimental support for 0.3 so that users can start testing.

The current WASI roadmap can be found here if you’re interested.

Debugging

One of the biggest arguments that I’ve heard against WebAssembly adoption over the years is a lack of tooling support with debugging being a major hurdle. Debugging support still varies by programming language but things have improved quite a bit since WebAssembly was first released. 

When the MVP of WebAssembly was first introduced in 2017, debugging options were limited. You could use a printf approach where you would send information to the console as the code executed. Or, you could use the browser’s developer tools to examine and step through a module’s WebAssembly Text Format (WAT) representation of the code. It was something at least but it definitely wasn’t an ideal way to debug your code.

In 2019, Chrome started adding in DWARF support but Firefox opted to go with source maps. In both cases, you still needed to use the browser’s developer tools to work with it but these options brought the ability to step through your original source code rather than the WAT code. This made things easier to work with because the WAT representation of the code doesn’t know information like variable names making things difficult to follow if there are a lot of variables.

DWARF is a debugging format that gives debuggers the information they need to map the low-level machine code instructions back to the original source code. 

The following article gives a quick glimpse into how things looked with WAT debugging, then source maps, and finally DWARF debugging when it was first being introduced in browsers.

There’s still work to do but fast forward to 2025 and debugging has improved. Now, debugging can often happen from within your IDE without needing to use the browser’s developer tools. This video from WASM I/O in March of 2025 gives a good example of this in action by using the LLDB debugger from VS Code to debug WebAssembly executing in a stand-alone runtime.

For some programming languages, like .NET, debugging from the IDE is possible without going through LLDB. .NET interacts with the browser directly through a debugging proxy. In November, .NET went a step further and announced the ability to do performance profiling as well as extract diagnostic data as shown in this video.

Adoption

Every year, WebAssembly’s use continues to grow in the browser. Based on the Chrome Platform Status metrics (click the ‘Show all historical data’ checkbox), of the number of websites visited by Chrome users, the sites using Wasm have increased by almost 1% again this past year to now sit at 5.5%. We’re not told what the total number of websites visited overall are but this is a potentially large amount given the number of sites on the internet. This count doesn’t include Safari, Edge, or Firefox browsing figures either so the percentage is likely even higher. 

Almost all of the top 25 programming languages have some WebAssembly support including Kotlin’s recently released beta compiler mentioned earlier. Although some popular languages, like SQL, might not compile to Wasm, it’s possible for SQL to leverage WebAssembly. For example, SQLite and MySQL Heatwave allow for the creation of WebAssembly-based User-Defined Functions (UDF) in the database that your SQL can then call.

I recently had the opportunity to do the technical review of the “Server-Side WebAssembly” book and one of the coding projects was the creation of a Wasm UDF for SQLite. The book also has a lot of interesting projects demonstrating how WASI and the Component Model work making it an interesting read.

WebAssembly’s use outside the browser is growing rapidly in many different locations including IoT, embedded devices, serverless, edge, cloud native, application code calling into Wasm modules or implementing plug-in systems and the list goes on. 

IoT devices are a subset of embedded systems where they have an internet connection allowing the device to communicate and share data. Embedded devices are a broader group where their focus is on a specific task, can operate independently, and usually with very limited resources (e.g. an engine control unit).

One example of WebAssembly’s use in the embedded devices space is demonstrated by a company called Atym. They have a runtime that can work on devices with as little as 256 KB of memory and the runtime uses containers that can be distributed via standard Docker repositories. It’s even possible to leverage AI with this system by using TinyML. The following video gives a demo of this in action: https://youtu.be/iDpG1yFDW1g

Edge computing is one many areas that takes advantage of WebAssembly’s small size, fast startup times, and security model. Cloudflare, Fastly, and Fermyon are some of the edge computing companies currently leveraging Wasm. For the past year, Fermyon has been working with Akamai, considered the largest CDN company globally, and it was just announced that Akamai is buying Fermyon in order to embrace the promise of WebAssembly.

People are using WebAssembly in a lot of interesting ways and one that stood out for me recently was the idea of compiling PHP and WordPress to Wasm. The aim is to run a WordPress website on the edge where you’d have a CDN type setup for your website. This can give low latency because it’s potentially closer to your user than a server might be. It can also reduce your costs because, rather than having a server that’s running all the time, your website spins up when a request comes in and then shuts down once the request is complete. This should result in less energy used, which is better for the environment, and also allows your website to scale based on demand. The following talk from WASM I/O goes into detail about how this works: 

With 2025 now behind us, let’s take a look at what the possibilities are for this year.

Expectations for 2026

Given that all browsers support the WebAssembly CSP proposal, it’s possible that this feature will be standardized this year.

Firefox has announced that they plan to bring the Branch Hinting feature out from behind a flag with their release that’s expected to ship in late February. With this change, all browsers will support this proposal.

  • The Branch Hinting proposal’s aim is to help improve the performance of modules by giving engines hints about which paths are most likely to be executed.

The Type Reflection specification is something that I expected to move to phase 4 in 2025 because it has been behind a flag in all browsers for some time now.

  • The Type Reflection proposal is meant to allow the WebAssembly JavaScript API to query information about the data types of functions imported and exported from a module.

Apparently, one reason why the proposal hasn’t moved forward is because it no longer has a champion. 

In late 2025, I was surprised to see that the team is considering demoting this proposal back down to phase 2 for two reasons:

  • The first reason being the need to find a new champion.
  • The second reason for the suggested demotion is because the specification may need some updates to reflect changes made by other proposals.

Safari

Over the past few years, Safari has done a lot of work to catch up to the other browsers in terms of Wasm support and I don’t see any indication of that slowing down. I’m hopeful that we’ll see support added for the following features in 2026 because they’re now standardized and live in the other browsers:

  • Multiple memories
  • Memory64
  • Relaxed SIMD

Safari had some concerns about the JavaScript Promise Integration (JSPI) proposal initially but removed their objection in late 2025. With the proposal now at phase 4, and because Safari now has someone assigned to a ticket to implement the feature, I’m hopeful that we’ll hear more about this before the end of the year.

JSPI is still behind a flag in Firefox so there’s a possibility that this will come out from behind the flag in Firefox this year as well.

There is a workaround that’s possible until the JSPI feature becomes available by using Asyncify. It doesn’t work as well, which is why this proposal exists, but that might be an option if your module needs asynchronous support in the meantime.

Other features that are possible this year

ESM - Source Phase Imports

ESM stands for ECMAScript Modules and is a standard format for the packaging of JavaScript code for reuse.

Right now, to call a function in a WebAssembly module, you need to fetch the .wasm file and instantiate it manually as shown in the following example:

JAVASCRIPT
const req = fetch("./myMath.wasm");

WebAssembly
  .instantiateStreaming(req, { …imports… })
  .then(res => { 
    console.log(res.instance.exports.add(1, 3)); // Prints 4 to the browser’s console
  });

The eventual goal with the ESM Integration proposal is to be able to just use the import keyword and the host would handle the downloading and instantiation for you. This is referred to as evaluation phase imports and the following is an example of what this could look like:

JAVASCRIPT
import { add } from ‘./myMath.wasm’

console.log(add(1,3)); // Prints 4 to the browser’s console

It was decided that a first step towards supporting evaluation phase imports would be implementing source phase imports as shown in the following example:

JAVASCRIPT
import source mathModule from "./myMath.wasm";

const myInstance = await WebAssembly.instantiate(mathModule, { …imports… });
console.log(myInstance.add(1, 3)); // Prints 4 to the browser’s console

In last year’s article I didn’t have an expected timeline but things are further along now. The specification is being worked on in the WHATWG W3C group and is now at stage 3.

Chrome and Firefox are currently working on this proposal. A ticket also exists for this with Safari but I’m not sure of the status beyond that.

I’m hoping to see this made available for testing this year.

.NET

After the release of .NET 10 in November 2025, a planning kickoff meeting happened in December for version 11. A follow-up meeting was held in January to answer questions and give insights into .NET plans from the web browser side of things. The January meeting can be found here if you’re interested.

Every release of .NET includes improvements around WebAssembly and that’s expected to continue with .NET 11 but more incrementally for this version. The reason for only incremental improvements this time is because they’re working on transitioning from the Mono runtime to the CoreCLR runtime and don’t want to put effort into a big feature only to have to redo it in the new runtime. 

That said, the team is looking into adding some features into version 11 to make developer’s lives a bit easier. One example is a web worker template to make it easier for WebAssembly logic to run in a background thread, rather than in the browser’s main UI thread, which would help keep the UI responsive.

A preview of the new CoreCLR runtime is expected in .NET 11 but it’s not expected to officially ship until .NET 12 in 2027. When the new runtime is released, they plan to target WebAssembly 3.0 which is interesting because that version includes features like Garbage Collection and Memory64.

Another exciting thing to watch out for this year is the Uno Platform’s work towards implementing multithreading.

WASI

The Component Model is currently being adjusted with native async support and the WASI worlds are being modified to take advantage of the new async capabilities. This part of the work is expected to be complete in February of this year and will be released as WASI 0.3.

Once 0.3 has been released, a series of 0.3.x releases are expected to add in additional async features like cancellation tokens, stream optimizations, and threads to name a few. The following link gives more information about the 0.3 roadmap if you’re interested.

The WASI 1.0 release is then expected to happen in late 2026 or early 2027.

As work has been happening on the features for 0.3, the Component Model proposal is also being refined. A lot of people have been watching this proposal for a while and were asking why it’s still at phase 1. I’m pleased to report that things are about to change. There was a suggestion of possibly advancing the proposal to phase 2 once WASI 0.3 is released, so that’s possible, but it’s definitely expected to start moving up through the phases once WASI 1.0 is released.

In Conclusion

2025 was another great year for WebAssembly-related progress. This past year saw several features, like Exception Handling with exnref and JavaScript String Builtins, become available in Safari rounding out support in all major browsers. We also saw several proposals advance through the standardization phases. On top of that, WebAssembly 3.0 was announced bringing a host of new features into the main specification.

We saw the release of Kotlin’s beta Wasm compiler, the release of .NET 10, and several releases of the Uno Platform that brought performance improvements with each release. The Uno Platform also announced a collaboration with Microsoft that will see a focus on bringing multithreading into .NET’s WebAssembly story.

The Bytecode Alliance has been busy adding async support to WASI in preparation for a 0.3 release. With that work, the Wasmtime runtime now has experimental support for WASI 0.3. The 0.3 release is expected in February of this year with a potential 1.0 release by the end of 2026 or early 2027.

The Component Model proposal is being worked on at the same time as WASI 0.3 and is expected to start advancing through the specification phases either after the 0.3 or 1.0 release.

We also saw that tooling is maturing as debugging options continue to improve for DWARF support and the LLDB debugger allows you to debug Wasm in stand-alone runtimes from VS Code. Some IDEs even integrate with browsers so that developers can debug in the IDE rather than in the browser’s developer tools. This past year, we also saw .NET add in the ability to do performance profiling and extract diagnostic data.

WebAssembly is gaining a lot of adoption but its use is more behind the scenes helping with portability, performance, and security. It’s a technology that’s not super flashy so it’s not always obvious that it’s being used which I think leads people to believe that it’s not as popular as it really is. In the browser over the past year, we’ve seen another 1% increase in use across websites that Chrome users visit to now sit at 5.5% in Chrome’s Platform Status metrics. Almost all of the top 25 programming languages support Wasm. In the cases where the language doesn’t compile to Wasm, like SQL, we’re seeing some of those languages leveraging WebAssembly in other ways like calling into Wasm-based User-Defined Functions.

Edge computing is one of many areas that are a natural fit for Wasm. In 2025, Fermyon was purchased by Akamai, the largest CDN company globally, in order to embrace the promise of WebAssembly. In related edge news, the ability to compile PHP and WordPress to Wasm so that it can run on the edge was demonstrated showing an interesting idea for how websites might be deployed in the future to reduce latency, reduce energy consumption, and scale better.

With the maturing of the WebAssembly specifications, developer tooling improving, programming language support growing, and the wide variety of areas where Wasm now runs, I have no doubt that 2026 is going to be another great year for WebAssembly. I think the biggest challenge for WebAssembly is marketing. We need to get the word out that Wasm is no longer an experiment. It’s ready for production. If you have something you want to build directly with WebAssembly, you can do that or you can also leverage Wasm by using tooling like the Uno Platform where you code in C# and it just works in the browser.