WASI and the WebAssembly Component Model: Current Status
WebAssembly (WASM) has evolved from a browser-based technology into a promising runtime for server and embedded applications. Key to this evolution are the WebAssembly System Interface (WASI) – a standardized set of syscalls for WASM outside the browser – and the emerging Component Model, which enables modular, language-agnostic composition of WebAssembly modules. This report analyzes the current status of WASI (including its major runtimes like Wasmtime and Wasmer) and the Component Model, focusing on the technical limitations that impede adoption. We draw from official proposals, runtime issue trackers, academic studies, and industry experiences to highlight critical gaps, unresolved bugs, and feature requests. Case studies illustrate how these challenges block real-world use cases, and we conclude with recommendations for improving WebAssembly’s performance, security, and integrability with host environments.
Overview
WASI Overview: WASI is a modular system interface that gives WebAssembly modules controlled access to operating system features such as files, clocks, and networking. It was created to extend WebAssembly beyond browsers, where vanilla WASM had no direct OS access due to sandboxing (1) (1). Early versions (WASI “snapshot preview1”) provided basic POSIX-like functions (e.g. file IO, environment vars, random) but notably lacked capabilities like networking and threading. In early 2024, the Bytecode Alliance released WASI Preview 2 (also called WASI 0.2), a major iteration that incorporates the Component Model and expands available APIs (2) (2). WASI 0.2 introduced “worlds” – cohesive sets of interfaces for specific domains. For example:
- wasi-cli for command-line apps (arguments, environment) (2),
- wasi-http for outbound HTTP requests (2),
- wasi-filesystem for files and directories (2),
- wasi-sockets for TCP/UDP socket support (2), and others like clocks and random number generation (2).
This broadened API surface addresses some long-standing gaps (e.g. networking, which Preview1 lacked). The next WASI release (0.3 or “Preview 3”) due in 2025 is expected to add native asynchronous I/O support via the Component Model and upgrade existing APIs to use async primitives (2). Full WASI 1.0 stabilization will follow once these pieces mature (2).
Component Model Overview: The WebAssembly Component Model is a newer proposal (currently in draft) that standardizes how larger applications can be built from smaller WebAssembly components. It builds on Interface Types (now embodied as WIT, the WebAssembly Interface Definition Language) to allow high-level data (strings, structured records, etc.) to be passed between modules, rather than only integers and linear memory references. In practical terms, the Component Model lets developers treat WebAssembly modules like “LEGO bricks” that plug together securely and interoperably (3) (3). WASI 0.2 is tightly coupled to the Component Model: interfaces are defined in WIT and can be assembled into components that import/export those interfaces. This enables dynamic linking and language interop – for example, a C-written module could call a Rust-written module’s functions if both conform to the same interface contract. Early implementations of the Component Model exist (e.g. in Wasmtime), but it is still in the proposal phase (Phase 2/3 in the W3C process) and not yet supported in web browsers (4: Timeline for the Component Model and async questions #316 - GitHub). As of late 2024, Wasmtime was the first major runtime with full support for loading Component Model modules (WASM components) and the WASI 0.2 APIs, while others are catching up (5). This means developers can experiment with multi-module applications in Wasmtime today, using the new WIT-based interfaces, though cross-runtime portability will improve as the spec stabilizes.
Major WASI Runtimes: Several WebAssembly runtimes implement WASI to varying degrees, each with their own focus:
- Wasmtime (Bytecode Alliance) – A fast, secure runtime in Rust that prioritizes standards compliance. It quickly integrated WASI Preview 2 support (5: About Wasm and WASI, I'll try ( and probably fail ) to escape the HN ...) and provides both JIT and ahead-of-time (AOT) compilation. Wasmtime also supports experimental features like asynchronous host calls (via Rust
async
/await
integration) to avoid blocking the runtime thread during host IO (6). Recent releases (e.g. Wasmtime v25) added full WASI 0.2.1 support and other improvements (7: Wasmtime v25.0 brings extended constants, WASI 0.2.1, user stack ...). - Wasmer – Another popular Rust-based runtime, emphasizing ease of embedding and cross-language bindings. Wasmer supports WASI Preview1 fully and has added Preview2 support in its 3.x/4.x releases, though historically it lagged slightly behind Wasmtime on new proposals. Wasmer introduced “WASIX,” a fork of WASI Preview1 with additional non-standard syscalls (like
fork()
, extended networking, etc.) to meet user needs while the official WASI progressed slowly (8) (8). This highlights both Wasmer’s innovation and the ecosystem’s fragmentation risk (discussed later). Wasmer plans to align with the Component Model and is working on async support, leveraging the browser’s upcoming WASM Promise integration to maintain parity between server and browser environments (6) (6). - WasmEdge – A CNCF project (formerly SSVM) focused on cloud and edge use-cases. WasmEdge supports WASI (Preview1) and went further by implementing non-blocking sockets and HTTP as extensions before these were standardized (9: WasmEdge Features | WasmEdge Developer Guides) (10). Performance is a key goal; it uses optimizations like AOT compilation. However, as of early 2023, WasmEdge had not yet integrated the new Component Model or Preview2 APIs, sticking to its own extensions for needed functionality (11) (11).
- WAMR (WebAssembly Micro Runtime) – A lightweight interpreter/AOT runtime optimized for embedded devices. WAMR implements WASI Preview1 (basic filesystem, args, etc.) but often omits heavy features. Notably, WAMR showed very fast startup and certain IO performance in tests (12), though it lacks support for multi-threading and other advanced proposals, focusing on minimal footprint.
- Node.js – Node introduced a built-in
node:wasi
module to run WASI modules in a Node process. However, this remains experimental and behind flags (e.g.--experimental-wasi-unstable-preview1
for Preview1 support) (11). Moreover, Node’s WASI has known security limitations: it does not implement the full sandboxing guarantees of WASI (for instance, file system access isn’t strictly confined to pre-opened directories) (13). The Node docs explicitly warn that it “does not provide the comprehensive file system security” of other WASI runtimes (14). In fact, Node’s maintainers caution users not to run untrusted WASM code usingnode:wasi
because the sandbox may be bypassable (13). This limits Node’s usefulness for secure isolation, though it’s fine for trusted code. The community has responded by instead embedding Wasmtime or Wasmer in Node when strong isolation is required (13) (13). Node has yet to mark WASI support stable (15: Request: mark WASI as stable · Issue #46254 · nodejs/node - GitHub). - Other – Browsers themselves do not natively support WASI (since it’s designed for non-web). Projects like wasi-js and wasm-polyfills exist to simulate WASI in a browser by shimming calls to JS APIs (16: swiftwasm/uwasi: Micro modularized WASI runtime for JavaScript), but these are incomplete and often limited by browser security (e.g. no raw socket access in browser). Some language-specific runtimes (like wasi-libc for C or wazero in Go) implement WASI to allow running WASM code within those ecosystems.
In summary, the ecosystem is in flux: Wasmtime leads on implementing the latest standards (Preview2, components, threads, etc.), Wasmer/WasmEdge have bridged gaps with custom extensions, and Node and others are still stabilizing their offerings. This uneven support across runtimes is itself an adoption challenge – as a CNCF survey noted, inconsistencies between runtimes and language toolchains are “amongst the biggest barriers facing Wasm developers” (17) (17). Next, we delve into specific technical limitations and gaps in WASI and the Component Model that underlie these challenges.
Key Technical Limitations in WASI
Despite significant progress, today’s WASI and related proposals still have important limitations. These gaps can hamper real-world use cases and require workarounds or non-standard extensions. Below we outline the most prominent technical issues:
1. Single-Threaded Execution: WebAssembly (and by extension WASI) began as a single-threaded sandbox. There is a threads proposal for WASM (enabling multithreading with shared memory), but it’s not yet universally deployed. Consequently, WASI programs cannot spawn or use multiple CPU threads by default. This has a direct impact on performance for compute or I/O heavy workloads on multi-core systems. For example, an academic evaluation of WASM “micro-container” performance found that a WASI-based server could only utilize one CPU core and saw severely reduced throughput compared to a native container because “the Wasm container does not support multi-threading” () (). The study concludes that the “lack of multi-threading severely limits its use cases” and that current WASM containers “do not match the performance of traditional Linux containers” for multi-core workloads (). There are experimental efforts to bring threads to WASI (e.g. the wasi-threads proposal and libraries () ()), but as of 2024 these are not part of the official WASI Preview2 and not supported in mainstream runtimes. This is a critical gap for server-side adoption, where multi-threading is the norm for scalability. Until threads are standardized and implemented (likely requiring the WebAssembly threads proposal to reach maturity), use of WASM in multi-core server apps will either be limited to single-core performance or rely on heavier-weight strategies (like running multiple WASM instances behind a load balancer).
2. Incomplete Networking and System Services: The initial WASI snapshot (preview1) deliberately omitted certain system functions, most glaringly network socket creation. It provided APIs to operate on already-opened sockets or file descriptors, but no way to open a listening socket or initiate a connection on its own (10). This made it “impossible to support some of the most popular features” – a clear example being that one could not write a pure-WASI HTTP server in Go or Rust because there was no way to call socket()
or bind()
(10). Developers worked around this in non-standard ways: Wasmer and WasmEdge added custom extensions for socket creation outside of the standard (often referred to as WASI-ext or WASIX) (10), and community libraries like stealthrocket/net
for Go provided shims to call those host-specific APIs (10). The good news is that WASI Preview2 has introduced wasi-sockets, providing standard APIs for TCP/UDP and making networking a first-class citizen (2). However, using these new APIs requires the Component Model and preview2 ecosystem – existing Preview1 binaries remain stuck without networking unless recompiled or adapted (18). Beyond networking, other OS features are still absent or limited in current WASI: there is no concept of process creation (fork/exec), no built-in inter-process communication (aside from pipes or sockets if provided), and no signal handling for things like graceful termination. These are important for complex applications or certain languages’ runtimes. For example, a POSIX fork()
would be hard to sandbox and was initially considered out-of-scope for WASI, but enough users needed it that the Wasmer team’s WASIX fork added a fork()
syscall and other POSIX functions (8) (8). This is controversial (adding a Unix-style fork in a modern sandbox breaks some expectations (8)), but it underscores that some existing software expects these capabilities.
3. Filesystem & Path Behavior Differences: WASI takes a capability-based approach to the filesystem – an embedder pre-opens specific host directories for the WASM module, and the module can only access files through those directory handles. There is no implicit “current working directory” or global filesystem namespace as in a normal OS process, which was a design decision to improve security and portability. However, this caused friction for porting certain applications. Developers found that common operations like chdir
(change directory) or getcwd
(get current directory) were not available, and C/C++ code relying on these would fail or need emulation. One user advocating for CLI tool support noted that to seamlessly ship a cross-platform CLI as a single .wasm binary, WASI’s behavior should match native as closely as possible. The lack of chdir/getcwd
meant there were edge-case inconsistencies (e.g. the result of getcwd
under emulation wouldn’t notice if the host moved the directory, etc.) (19) (19). They proposed extending WASI with explicit chdir
and getcwd
calls to eliminate these differences (19). WASI’s developers did eventually add a form of chdir
in the filesystem proposal (as part of WASI Preview2’s filesystem API, if the host opts to allow it), but this took time. Another subtle file-system issue is path handling across platforms – WASI uses a simplified POSIX-like model (forward slashes, UTF-8) and there have been long discussions on how to reconcile Windows vs Unix path semantics in a way that doesn’t leak host specifics (20: Standardizing WASI: A system interface to run WebAssembly ...). The overarching theme is that WASI started minimal for security and simplicity, but real-world apps often needed more of the “messy” OS details. Capabilities like working directory, relative paths, symlink resolution, file renaming, etc., had to be gradually introduced without compromising safety. Some gaps remain; for example, secure sandboxing of the filesystem is not automatic – the embedder must correctly preopen directories. Node’s WASI module infamously did not restrict access properly by default, leading to the warning that it wasn’t secure (13) (13). Going forward, the filesystem API in WASI will likely grow to cover more of POSIX (the WASI-filesystem proposal includes functions analogous to openat()
, renamed
, etc.), but striking the right balance between full POSIX fidelity and WebAssembly’s portability goal is an ongoing challenge.
4. Lack of Built-in Async I/O: As of WASI 0.2, there is still no native asynchronous I/O in WASI. Traditional OS interfaces often allow non-blocking operations or an event loop (epoll, etc.), but WASI Preview1 offered only a rudimentary poll_oneoff
function for limited polling of file descriptors. This means that if a WASM module wanted to perform IO without blocking its single thread, it required host cooperation or library routines. Wasmtime internally uses async Rust (via tokio) to implement WASI calls, but from the WASM program’s perspective those calls are synchronous and will block execution until completion (12). The Component Model is expected to resolve this by letting imports be defined as async and integrating with WASM’s future async support (there’s an upcoming WASM Promise Integration proposal for the JS API (6)). In fact, WASI 0.3 (Preview3) is slated to introduce native async support so that, for example, a WASI TCP socket read can await data without freezing the entire instance (2). Until that materializes, any I/O-heavy WASI program is either forced to be single-threaded synchronous or to use non-standard tricks. This is a barrier for high-performance network services (one of WASM’s target domains, like microservices and serverless). Early adopters have used workaround patterns: some use multiple WASM instances to simulate concurrency, others rely on callbacks from the host to wake the WASM code with data (which is complicated without standardized async). This limitation also complicates embedding WASI modules in async hosts: for example, an async Rust app embedding Wasmtime had to enable an async calling context to prevent blocking on WASI calls. Wasmtime added an async configuration to pause and resume fibers for WASI calls (6: Introducing Wasmer 5.0 : r/rust), but not all runtimes have this. In short, lack of async was a known gap and is being actively fixed, but in the interim it has limited WASI’s suitability for network servers and any case requiring overlapping I/O operations.
5. Memory Sharing and Communication: By default, each WebAssembly module has its own linear memory. WASI and the Component Model did not initially provide a way to share memory between modules or with the host except via explicit copying. This means that if a host application wants to hand a large dataset (say a 100MB image) to a WASM module, it typically must copy it into the module’s memory or use some manual mechanism (like memory mapping to a file descriptor). This copying can be a performance bottleneck in scenarios that require high throughput interactions between host and WASM. The new Component Model and recent proposals like Multiple Memories aim to alleviate some of this: modules can have multiple linear memories and possibly share one memory between components (2) (2). But multiple memories are brand new (standardized in 2024) and not widely utilized yet. So currently, one general performance constraint in WebAssembly is the overhead of crossing the boundary – calls from host to WASM or vice versa incur copying or marshalling costs, especially when complex data is involved. The Component Model’s interface types will eventually allow passing, for example, a string or list without manual copying (the engine will translate it under the hood), but at present, many toolchains still lower everything to raw pointers and lengths, causing conversions. Indeed, a point of discussion in the WASI community was how strings are passed: today they are often passed as pointer/length (two i32 values) which is web-unfriendly and not the most efficient (21). The plan is to replace that with native string types once interface types are fully available (21) – this should improve both performance and developer ergonomics. Until then, CPU overhead of serializing/deserializing data is a minor adoption hurdle; in tight loop scenarios, WASM <-> host communication can become a bottleneck. (One early observation was that DOM calls from WebAssembly in the browser were slower than expected due to crossing the JS/WASM boundary frequently (1) (1: WebAssembly’s Moment: Wasm Has Problems, But There’s A Solution) – a similar principle applies outside the browser with host API calls.)
6. Tooling and Debugging Gaps: Another often-cited limitation is the relative nascency of the developer tools around WASI. Debugging a crashing WASM module running under WASI can be challenging – until recently there was poor support for high-level debugging (setting breakpoints in the original source, etc.). Although projects like wit-bindgen
and language-specific WASI SDKs exist, the maturity of toolchains is uneven. For example, languages like Python, Ruby, and C# only got basic WASM/WASI support in the last year or so (22), and their runtime support (e.g. garbage collectors working inside WASM, exceptions mapping, etc.) is still a work in progress. The community has noted that “lack of dev tool maturity is the real time waster” in the current state of WebAssembly, even more than missing features (8) (8). This includes profiling tools (to find performance issues in JIT compilation or WASI calls), packaging and module distribution (the ecosystem is experimenting with WASM component registries, WAPM, etc., but not consolidated), and testing frameworks. The Component Model again is expected to help by standardizing how different languages express their interfaces (so that ideal “WASM bindings” frameworks can flourish, letting you call code across languages seamlessly). But as of now, each language has its own set of limitations when targeting WASI. For instance, the Go 1.21 WASI support passes most tests but still surprises users with the fundamental limitations of the platform (no threads, no true parallelism, blocking syscalls block all goroutines) (10) (10). These are documented, but a developer coming from native Go might not expect their WASM build to behave quite differently under load. Improvements in documentation and developer education are gradually filling this gap – e.g. the Go team explicitly enumerated such gotchas in their WASI port announcement (10) (10).
In summary, WASI’s technical gaps – missing multi-threading, historically no networking, partial OS feature coverage, lack of async, data passing overhead, and immature tooling – collectively hinder some “real-world” applications from being ported or built with WebAssembly today. Many of these are being actively addressed by ongoing proposals (threads, component model async, etc.), but until those are standardized and broadly implemented, developers either have to accept limitations or use custom solutions. Next, we will see how these limitations manifest in practice via community-reported issues and case studies, and how they affect adoption.
Community Challenges and Unresolved Issues
The WebAssembly and WASI community has been actively voicing pain points on GitHub, Reddit, and other forums. Examining these discussions helps illuminate what real users need and where current implementations fall short. Below we compile notable issues and feature requests from major runtime trackers and community dialogues:
-
Performance Bottlenecks in WASI Implementations: A stark example came from a user benchmarking file I/O in Wasmtime vs native. They found a simple program writing to a file was 10x slower in Wasmtime (23 seconds) than native (2 seconds) (12). Investigation revealed that Wasmtime’s WASI implementation (at that time) used the async Tokio engine even for synchronous writes, leading to excessive syscall overhead and context switching (12) (12). In fact, an
strace
showed Wasmtime performing three times more system calls than the native counterpart for the same workload (12) (12). The developers acknowledged this as a bug to be optimized (12). This case underscores that performance parity with native is not guaranteed, especially for system call-heavy operations. Each runtime’s internal design can greatly affect throughput: e.g. Wasmtime favored an async, capability-safe design at some cost to raw speed, whereas WAMR (which had a more direct approach) outperformed it in this test (12). Similar performance issues have been reported for specific patterns – another issue noted certain arithmetic operations being slower in one runtime versus another (23: Performance issue in some kinds of compound operations #6287), highlighting that compiler backends (Cranelift vs LLVM, etc.) still have optimization gaps. While WebAssembly is often touted as near-native speed, these reports show that suboptimal paths in runtimes or missing JIT optimizations can lead to unexpected slowness, which might deter users if not addressed. The good news is that such issues, once identified, usually lead to improvements in subsequent releases (e.g. by mid-2024 Wasmtime and Wasmer both made significant performance tuning to their I/O and code generation). -
WASI Preview Version Incompatibilities: The jump from WASI Preview1 to Preview2 (WASI 0.2) introduced breaking changes – not just new features but a new way to define the interface (WIT components instead of the old
wasi_unstable
interface). This means binaries compiled against WASI Preview1 are not compatible with Preview2 without adaptation (18). Developers have expressed frustration at having to rebuild or use shims. For example, an Hacker News discussion on “WASI 0.2.0 and Why It Matters” pointed out that “it is not compatible with existing WASI functions… you need to change your binary with an adapter to get existing WASI binaries to run [on] preview2” (18: WASI 0.2.0 and Why It Matters - Hacker News). The Bytecode Alliance anticipated this and provided a preview1-preview2 adapter tool (24) (24), but this extra complexity can impede adoption. A library author might hesitate to ship a WASM module if users then have to worry about which WASI version their runtime supports. To mitigate this, Wasmtime continues to support both preview1 and preview2 in parallel (and likely will for some time) (25: wasmtime_wasi - Rust - Docs.rs), and there are efforts in WASI to define a versioning strategy so that such breaking changes are minimized post-1.0 (26: Wasmtime and Cranelift in 2023 - Bytecode Alliance). Nonetheless, in 2023-2024 we’re in a transitional period where WASI is evolving quickly, which ironically can slow adoption since some developers adopt a “wait until it stabilizes” stance. The AssemblyScript team’s decision to remove WASI support is one example – while their reasons were more ideological (concern about web-incompatibility), it means any AssemblyScript module cannot use WASI until further notice, limiting its use outside the browser (27). -
Web vs Non-Web Tensions: A recurring theme is the divergence between WebAssembly’s use on the Web (in browsers) and outside. Some web-focused developers worry that WASI is introducing concepts that don’t translate to browsers, thus fragmenting the ecosystem. This concern was vocalized in both the AssemblyScript case and earlier discussions in the WebAssembly community. AssemblyScript maintainers objected to WASI APIs that can’t be polyfilled in a browser (like sockets or certain filesystem calls), arguing it breaks the “compile once run anywhere” ideal (27) (27). They felt the WASI subgroup was catering to OS use-cases “incompatible with JS and existing web standards” without clear communication (27). Similarly, a GitHub issue titled “May WASI turn out to harm Wasm on the Web?” raised the point that a pure WASI application cannot run on the Web, and if popular libraries start depending on WASI, it could leave the web platform behind. Emscripten’s lead contributors noted they tried adopting WASI for certain use cases but found “much of it was too inefficient on the Web” and thus couldn’t use it for browser-targeted builds (21). They suggested perhaps a web-specific system interface (“WASI for Web”, jokingly dubbed WABI) might be needed if WASI continued focusing on non-web capabilities (21). The WASI developers responded that web and non-web builds can be separate but share tooling, and indeed, the idea now is to have different “worlds” or profiles – e.g., a component can be built for a WASI world or a DOM (browser) world with different imports. This fragmentation is a concern because it complicates portability: developers may need to compile different WASM binaries for browser vs server, or include fallbacks. It somewhat contradicts the hope that WebAssembly would let one binary run anywhere. The community seems to accept some split as unavoidable (browsers will never allow raw socket access for good reasons), but the key is minimizing divergence. This is why proposals like “wasi-http” are interesting – they could allow a WASM module to make HTTP requests in a portable way, and in a browser that could be implemented on top of
fetch()
whereas in WASI it uses sockets. Such efforts are ongoing to bridge the gap. The impatience in the community is notable: a 2023 survey found that satisfaction with the evolution of WASI was significantly lower than satisfaction with core WebAssembly features (28) (28). Many respondents expect WebAssembly to eventually fulfill the “write once, run anywhere” promise of Java, but clearly we’re not fully there yet (28) (28: The State of WebAssembly 2023). -
Security and Sandboxing Concerns: While WebAssembly is often praised for strong sandboxing (memory safety and isolation), some discussions reveal edge-case security concerns. The Node.js WASI situation is one – Node chose not to implement a separate sandbox and instead relies on JS sandboxing, which means if a WASI module manages to escape or misuse the host APIs, it could do harm. The Node WASI module warns that secure sandboxing is not fully provided (14: WebAssembly System Interface (WASI) | Node.js v23.8.0 ...), and as one commenter put it, Node’s WASI doesn’t uphold the guarantees that would allow safely running untrusted code (13). They explicitly conclude “do not run untrusted code on it” (13) (13). By contrast, Wasmtime and Wasmer’s WASI implementations are designed with a strong sandbox – they don’t automatically trust the module with anything not given. However, a subtle security challenge is ensuring the host integration is correct. For example, there was an issue about
path_open
in Node not using the proper system call (openat
) under the hood, which could potentially allow directory traversal outside preopens (13). These kinds of bugs can crop up and must be carefully handled in each runtime. Another security aspect is denial-of-service and resource limiting – running untrusted code means you may want to limit its CPU time, memory, or file access. WebAssembly runtimes do enforce memory limits (each module’s linear memory has a maximum), but limiting CPU or instructions executed is harder. There is no built-in “gas meter” in most WASM engines (except interpreters like WASM3 or WAMR which sometimes offer a step counter). Some runtimes (like WasmEdge) have added options for execution time limits or metering (29: The wasmedge CLI | WasmEdge Developer Guides), but it’s not standardized. Thus, a host embedding WASI modules needs external mechanisms (like running in a separate thread and killing it on timeout, or using an async callback for timeout). Stack overflow and stack depth in WASM are also concerns – Wasmtime and others set a guard page, but configuring it (to prevent potential security bypass via stack overflow) might require tuning (30: Can either wasmer or wasmtime handle 1M concurrent wasm ...). No major breakout vulnerabilities have been reported in WASI runtimes to date, but security is an ever-present concern that adoptors (especially cloud providers) scrutinize. Fastly’s CTO, in a 2024 piece, highlighted that robust sandboxing plus flexible interfaces is what finally allows “secure, fast and compatible” code outside the browser (3), implying that WASI 0.2’s improvements were necessary to achieve that vision. -
Fragmentation via Custom Extensions: The slower pace of the official standard process led to multiple “forks” or extensions. We’ve mentioned WASIX (Wasmer’s POSIX superset) – it added threads, signals, fork, etc., on top of WASI Preview1. Another example is Threading proposals: before any standardized solution, some attempted custom implementations (like an early proposal for WASI threads with a particular library ()). While these solve immediate needs, they risk fragmenting the ecosystem if they diverge. Matt Butcher of Fermyon described “The Fragmentation Grenade” as a top risk for WebAssembly – meaning different parties creating incompatible variants that split the community (22). Indeed, when WASIX was announced, some feared it would “compete with WASI Preview2… not good news for the Wasm ecosystem” (8). Wasmer’s team responded that they don’t intend to fork forever, but wanted to “give [standards] a nudge” by demonstrating needed features (8) (8). They insisted “WASIX does not compete with WASI, it enhances it by adding features from POSIX that most users need”, and expressed hope that those features could migrate into WASI in time (8) (8). This dynamic between pushing ahead vs. staying unified is a delicate balance. Other fragmentation examples include bespoke WASI implementations for niche domains (like wasi-nn for machine learning inference, which provides an API to run neural nets). If a WASM module uses WASI-NN, only runtimes supporting that proposal can run it. Thus, until such proposals are standardized or widely adopted, using them reduces your portability. The recommendation from leaders in the field is to collaborate in standards bodies (W3C, Bytecode Alliance, and CNCF WebAssembly WG) to incorporate popular extensions, and simultaneously for vendors to avoid gratuitous deviations. The Bytecode Alliance’s module compatibility matrix (24: Land WASI Preview 2 support into Wasmtime · Issue #6370 · bytecodealliance/wasmtime · GitHub) and CNCF surveys help track this, but it remains a challenge for developers: one must carefully choose which WASI features to rely on, or conditionally support multiple fallbacks.
Case Studies Impacting Adoption: To illustrate how these challenges block use cases, consider a few scenarios:
-
Serverless Function Provider: Imagine a cloud provider wants to let users deploy functions in WebAssembly (using WASI for filesystem and network). They need strong isolation (sandbox), multi-tenancy performance, and support for common runtimes (perhaps users code in Python, Go, etc.). In early 2023, if they tried this with WASI Preview1, they’d hit a wall with networking (no outbound sockets). They would either have to tell users “no network calls” (unacceptable for most apps), or maintain a custom patch (like an internal fork of Wasmtime with experimental socket syscalls). They’d also struggle with concurrency – all WASM instances are single-threaded, so handling many requests might require running many WASM instances, increasing overhead. Cold start times become an issue then (though WASM is generally faster to start than containers). Indeed, Fastly’s and Cloudflare’s explorations into WASM found that some workloads didn’t fit until threading and networking came into play. Now with Preview2’s wasi-sockets and upcoming threads, these use cases open up. But the case study here is: lack of networking and threads was a showstopper for adopting WASM in a general-purpose serverless platform. Fastly’s team explicitly celebrated WASI 0.2 as it “represents an official stabilization of the Component Model and collection of WASI APIs” needed for a robust foundation (3). In other words, only now (2024) do they consider the platform ready to build those “LEGO brick” style apps that they and others envisioned.
-
CLI Tools Distribution: A developer wants to distribute a command-line tool to many platforms. WebAssembly sounds appealing: compile once to .wasm, and users can run it on Windows, Linux, Mac via a WASI runtime. They port their C++ tool to target WASI. Immediately, they encounter that
chdir
and relative path handling aren’t like a normal OS. Their tool, which expects to start in the user’s current directory and manipulate files, behaves unexpectedly under WASI because everything is relative to preopened dirs andgetcwd
is not available. In an issue, they note differences between native and WASI builds and request better support for current directory handling (19) (19). Until that is resolved, their users might get confusing behavior (e.g., the tool might treat/
differently, or not follow symlinks as expected). This friction might lead them to delay offering a WASM version. This scenario shows how seemingly small gaps (like missinggetcwd
) can reduce confidence in using WASM for software distribution. It’s being improved, as WASI’s goals explicitly include supporting great CLI tools (19: Supporting an "initial current directory" · Issue #24 · WebAssembly/wasi-filesystem · GitHub), but it took time to catch up to what native devs expect. -
Language Ecosystem Buy-In: The AssemblyScript saga is a case where a community backed away from WASI due to philosophical differences. AssemblyScript (AS) is a TypeScript-like language compiling to WASM. Many saw it as a way to leverage web developers’ skills for both browser and server WASM. However, the AssemblyScript team felt that WASI’s direction (adding non-web APIs, using interface types that don’t align 100% with JS types, etc.) wasn’t in AS’s interest. They published an objections document and removed WASI from their standard library. The consequence: AssemblyScript modules can no longer easily access files or environment when run under Wasmtime/Wasmer; they are essentially sandboxed to browser-like capabilities. One commenter noted this will make it “impossible to run [AssemblyScript] outside the web”, isolating it from the growing world of WASI-enabled use cases (27) (27). They pointed out that AS will miss out on any WASI APIs that could be implemented on the web too, and that the AS authors seemed to misunderstand WASI’s purpose (27). Regardless of sides, this incident highlights an adoption blocker: if frameworks or languages don’t cooperate with WASI, users face a fragmented ecosystem. Someone picking AssemblyScript might not realize they can’t use it for a WASI plugin later, undermining the “universal” story of WebAssembly. The recommendation many had was that AssemblyScript could maintain a modular approach – e.g., let users opt-in to WASI if they want – rather than outright removal. This is a community coordination problem as much as technical. We might see it resolved if web-compatible subsets of WASI are defined, or if AssemblyScript changes course. But for now, it’s a real-world example of how disagreements on WASI’s design affected adoption in a language community.
-
Web Application Needing System Access: Consider a scenario with a web app that also has a desktop version, and the developers want to reuse code via WASM. They have some core logic (say a data processing library in C++) that they compile to WASM. In the browser, it runs with no WASI (just pure computation). For the desktop, they’d like it to read files or use network. They could compile a WASI-enabled version for the desktop and run it with Wasmtime. But they discover that the WASM binary needs to be different (one was
wasm32-unknown-unknown
, one iswasm32-wasi
). Now they have to ship two flavors or figure out dynamic adaptation. If they try to use the WASI binary in the browser via a polyfill, they find it’s “too inefficient” or that certain calls just can’t work. This hypothetical echoes actual developer remarks on inefficiency when trying to use one module in both web and WASI contexts (21). Until the Component Model possibly allows a single component to contain both web and WASI bindings, developers must navigate this carefully. It’s a barrier for those aiming for true cross-platform modules.
Overall, these community issues paint a picture of an ecosystem maturing but still experiencing growing pains. The next section offers recommendations and outlook based on these findings, focusing on what is needed to push WebAssembly and WASI into wider, smoother adoption.
Recommendations and Future Outlook
WebAssembly’s potential – fast, safe, portable code – has driven tremendous enthusiasm, but to realize it outside the browser, the WASI and Component Model infrastructure must fully address the highlighted challenges. Here we provide recommendations and note ongoing efforts, aligned with the problems discussed:
1. Accelerate Standards Completion, but Maintain Cohesion: Many of the current blockers (threads, async, component model in browsers) are known and are simply awaiting standardization and implementation. It’s crucial that the WebAssembly Community Group and Bytecode Alliance continue to push these to completion. The slower pace of standards was identified as a risk (22) (22) – so finding ways to accelerate without fragmenting is key. One idea is to define clear version milestones (as is happening with WASI 0.2, 0.3, etc.) and encourage runtimes to implement in parallel. The success of WASI Preview2 – reaching a “minimum viable” set of syscalls – is a big step; next, getting to WASI 1.0 with backward compatibility guarantees will reassure developers that the platform is stable. In tandem, the Component Model should reach Phase 4/5 (standard/implementation phase) as soon as practical, so that tooling ecosystems treat it as a given. Part of this involves browser vendors; while WASI is mainly for out-of-browser, the Component Model could also benefit web (for multi-module applications). Having at least two major engines (Wasmtime and Wasmer, for example) fully support the Component Model will signal its readiness. As of 2024, Wasmtime and experimental tools like componentize-py
, .NET componentize
are emerging, but broader language support is needed so that, say, a Python library can be automatically turned into a component and used from Rust or JS easily. Encouraging cross-collaboration (e.g., between Bytecode Alliance and projects like AssemblyScript) will help avoid duplicated efforts. The Bytecode Alliance’s open development and forums like WASM Implementers’ calls should continue to invite feedback from all stakeholders (web and non-web) to ensure the final standards meet general needs.
2. Prioritize Missing Features with High Impact: Based on the issues, the highest-impact missing features to address are: multi-threading, asynchronous I/O, and sockets (which is done in Preview2). The good news is all are in progress: Threads are in late stages for the core WASM spec (Phase 4) and some engines (browser and server) have experimental support, so we should expect WASI to adopt threads once that’s stable. It might also involve adding an API for thread creation in WASI (perhaps via a new wasi-threads
module) – designing that in a capability-safe way (without exposing full POSIX pthread
weirdness) will be important. Asynchronous I/O in WASI 0.3 should land in 2025, and the recommendation is to ensure it covers not only network sockets but also files and other operations, so that languages like Go or Node that rely on async patterns can integrate cleanly. It would also be wise to create guidance for embedding WASI in async hosts – e.g., official patterns for using an event loop with WASI modules (some of this exists in Wasmtime docs). For networking, beyond basic sockets, consider higher-level protocols: wasi-http (in Preview2) is an example of a high-level API for HTTP requests. That should be fleshed out and possibly expanded to things like gRPC or other common protocols via libraries on top of sockets. Additionally, missing OS features like signals or process management need clarity: if the goal is to support “everything a Unix process can do”, then perhaps a WASI proposal for subprocess spawning (with careful sandboxing, maybe like a controlled posix_spawn
that can only launch another WASM module) could be introduced. If that’s out of scope, it should be clearly documented so developers know to avoid those patterns or emulate in other ways.
3. Improve Performance through Engine Optimizations and Tooling: The performance issues identified can be mitigated by both low-level optimization and giving developers better insight. Runtimes should continue to optimize syscalls – for instance, Wasmtime might switch to a more direct IO implementation for synchronous writes to close the 10x gap seen in the issue (12). Efforts like Lucet (Fastly’s former AOT compiler) and ongoing Cranelift improvements can help WASM code execution speed approach native. There’s also the area of CPU feature exploitation: proposals like SIMD and new instructions (memory64, tail calls, etc.) that are now standardized should be leveraged in WASI environments for speedups. For example, heavy crypto or math in WASI can benefit from 128-bit SIMD now that it’s standard and available in Wasmtime, Wasmer, etc. Another angle is ahead-of-time compilation: shipping precompiled native code for a WASM module (when target architecture is known) can remove JIT overhead at runtime. Wasmer and Wasmtime both allow pre-compilation; developers should be encouraged to use this for production deployments. On the tooling side, providing profile-guided optimization or at least profiling tools for WASM would allow pinpointing hotspots (like the tokio issue) more easily. The community might benefit from a standardized benchmark suite (similar to SPEC) to measure WASI runtime performance across various tasks (IO, compute, startup) – this can drive competition and improvement. Indeed, independent benchmarks in early 2023 by Frank Denis (11) (11: Performance of WebAssembly runtimes in 2023 | Frank DENIS random thoughts.), etc., have been useful to identify slow spots; continuing such efforts and including more WASI-oriented tests (like networking throughput or multi-instance scaling) will be helpful.
4. Strengthen Security and Sandbox Tooling: To increase confidence in adopting WebAssembly for untrusted code, the runtimes should aim for provable security properties. This includes completing work on things like module sandboxing API (so a host can easily restrict a module’s resources) and auditing filesystem access controls (to avoid issues like Node’s). One practical recommendation is to implement mandatory access control logging: a WASI runtime could provide debug logs of every attempt to open a file or socket, which could help developers ensure their module only touches what’s intended. Also, integrating with container security contexts – e.g., running Wasmtime inside a Docker container with seccomp – can provide defense in depth. Perhaps provide templates or guides for that. Another idea is a WASM “jail” manager that can run WASI modules with configured limits (time, memory, etc.) and kill or pause them as needed – an analog to container runtimes but for WASM. Some projects (like wasmCloud, Fermyon’s Spin) are already building such orchestration; contributing back any generic tooling to Bytecode Alliance or CNCF could make it broadly available. Given Node’s WASI is not secure for untrusted code, a recommendation to Node would be either deprecate that in favor of an embedded Wasmtime, or revamp it to meet the WASI spec’s sandbox requirements (though that might mean rewriting parts in Rust or using a different approach). Until then, documentation should clearly state the limitations (which Node does, albeit in small print). For other runtimes, transparency about any sandbox escapes or CVEs and prompt fixes will be important to maintain trust.
5. Bridge the Web and WASI ecosystems: To avoid the Web vs. WASI split, efforts should be made to define a common subset and polyfills. For instance, the community could define a profile of WASI that is web-compatible (no forbidden syscalls) – AssemblyScript or other browser-focused toolchains could target that. At the same time, browsers could implement certain WASI proposals that make sense for them: one obvious candidate is the wasi-clock and wasi-random interfaces (browsers can supply time and randomness easily, which aligns with existing Web APIs). If those become standard, then a WASM module that just needs time or random doesn’t have to special-case between web and WASI – it can always use WASI calls, and the browser environment would just provide them (perhaps via JavaScript glue). Some discussion on a “WASI for Web” (maybe tongue-in-cheek called WABI) suggested making new web-focused APIs under the WASI umbrella (21) (21). That might be a good compromise: define, for example, a WASI-web API for things like DOM manipulation or fetch
networking, which would only be available in a browser embedder but follows the same component model approach. Over time, the difference between a “web assembly module” and a “WASI module” could then just be which world it imports (wasi-web vs wasi-cli, etc.), and using the Component Model, one could even produce a single .wasm package containing multiple variants. In the short term, better tooling to target multiple outputs (web and WASI) from one codebase would help. Emscripten already can produce a WASI output or a JS output; it could be made more seamless. Documentation should guide developers on how to maintain compatibility (e.g., use feature detection in the module to fall back to JS APIs if WASI imports aren’t present – some advanced users do craft modules that check imports at runtime). The goal is to minimize duplicate effort and ensure web use-cases are not sidelined even as server-side WASM blooms.
6. Enhance Developer Experience (DX): Lowering the barrier to entry for using WASI will drive adoption. This includes providing high-level language SDKs for WASI: for example, the Go team did a great job making GOOS=wasip1
mostly “just work” and documenting limitations (10). Other languages should follow suit (many are: Rust’s standard library has a WASI target, Python’s WASM story is improving with Pyodide and WASI support). Ensuring that languages can easily generate WASM components (not just raw WASM modules) will be important so that in the future one can, say, write a library in Python and use it as a component in a Rust program without hassle. Projects like componentize-py
, componentize-dotnet
are steps in this direction (2). More broadly, the community should develop testing frameworks and best practices for WASI modules. For instance, how do you unit test a module that expects certain preopened dirs or env vars? Possibly by having a lightweight host harness that simulates those. Efforts like wasmCloud’s “wash” CLI for local development aim to “bring the hot reload experience to WebAssembly” and streamline dependency resolution for components (17) (17). These are great for DX and should be expanded upon. The easier it is for developers to iteratively build and debug WASI apps (with tools akin to what they have for native or web), the more likely they are to adopt the tech. Another DX aspect is package management: the community might converge on publishing WASI binaries or components to registries (e.g., OCI registries via container images, or specialized ones like WAPM). Clear guidance on how to publish and consume WASM modules (similar to npm or PyPI but for WASM) would encourage a “plugin economy” using WASI. This ties into integration – e.g., if a database like PostgreSQL could allow stored procedures in WASM, one would need a way to distribute those modules conveniently.
7. Continue Community Engagement and Knowledge Sharing: Finally, sharing success stories and remaining hurdles openly will help the ecosystem mature. Case studies where WebAssembly was integrated (or where it failed to) should be documented. For example, if a company tried to replace a Docker microservice with a WASI module and encountered specific limitations, writing that up helps others anticipate issues and also provides feedback to runtime maintainers. The Bytecode Alliance and CNCF WebAssembly group are good forums for that. The community should also maintain an updated “WASI support matrix” covering each major runtime (Wasmtime, Wasmer, WasmEdge, Node, browsers via polyfill, etc.) and listing which features are supported to what extent. This transparency will let developers choose the right tool for their use case (for instance, knowing that “for multi-threading, only Wasmtime with an experimental feature flag supports it as of now” or “for running on iOS, maybe only Wasm3 interpreter works due to JIT restrictions” etc.). Right now information is scattered; consolidating it can reduce confusion.
In conclusion, WebAssembly with WASI and the Component Model is on the cusp of becoming a universal runtime for plugin systems, cloud computing, and beyond. The challenges identified – from technical gaps to ecosystem fragmentation – are those of a young but rapidly evolving technology. The current status is that many pieces (WASI 0.2, component model draft, runtime implementations) are in place, addressing earlier criticisms, but a few critical pieces (threads, stable async, broad adoption of component model) are just emerging. By methodically closing the remaining gaps and fostering collaboration over fragmentation, the community can unlock WebAssembly’s full potential. As these improvements land, we anticipate broader real-world adoption: more projects choosing WASM for safe plugin execution, more cloud platforms offering WASM as a deployment target, and even desktop or IoT applications using WASI to go truly cross-platform. The path is clear; now it’s about execution and refinement. With continued efforts, the vision of “secure, fast, portable code running anywhere” – hinted by many as WebAssembly’s promise – will be fully realized (3), ushering in a new era of software modularity and distribution.
Sources:
- Bytecode Alliance & WASI Proposals (WASI Preview2 content and roadmap) (2) (2: The State of WebAssembly – 2024 and 2025)
- Go WASI Support Announcement (limitations of WASI like no threads, no full sockets) (10) (10: WASI support in Go - The Go Programming Language)
- Reddit: Wasmer’s WASIX discussion (slow WASI progress, added fork and POSIX features) (8) (8)
- Reddit: AssemblyScript drops WASI (WASI vs Web incompatibilities debate) (27) (27: AssemblyScript has removed WASI support : r/programming)
- GitHub Issue: WASI too inefficient on Web (Emscripten team feedback) (21: May WASI turn out to harm Wasm use cases on the Web? · Issue #401 · WebAssembly/WASI · GitHub)
- GitHub Issue: Wasmtime IO Performance (10x slower than native due to tokio) (12) (12: Poor performance of wasmtime file I/O maybe because tokio · Issue #7973 · bytecodealliance/wasmtime · GitHub)
- Reddit: Node WASI not secure (Node’s implementation lacks sandbox guarantees) (13: Since Node.js' node:wasi is hopelessly broken in mysterious ways, here's to calling wasmtime from Node.js, Deno, and Bun : r/javascript)
- Fermyon Blog: Risks of WebAssembly (risks of slow standards and fragmentation) (8: Announcing WASIX - the Superset of WASI : r/rust) (22: The Risks of WebAssembly)
- Fastly Blog: WASI 0.2 launch (overview of component model and new capabilities) (3) (3: WASI 0.2: Unlocking WebAssembly’s Promise Outside the Browser | Fastly)
- wasmCloud Blog: Wasm adoption barriers (survey citing inconsistencies between runtimes) (17: wasmCloud spurs Wasm adoption with major DevEx improvements | wasmCloud).