Question from someone knew very little in this domain: what stops mass adoption of WebAssembly?
A few years ago, I used a WASM demo website which can use a WASM version of ffmpeg to mux audio and video into a file (transcoding obviously wasn't practical, at least not at that time), and I was very impressed. I can see lots of potential of it.
But I still haven't see much usage of it even today.
(To be totally honest -- i'd rather it's not popular because it would make debugging websites/web applications close to impossible; but that's besides the point.)
3. Google Docs (word processor) uses WASM for offline proofing
These are just examples. If you look at the pattern the transition isn't happening in a way that all softwares are entirely targetted for webassembly. It's happening in little steps leveraging webassembly to parts of the product where it makes sense. This I believe is how the transition should be as opposed to jumping all the way to webassembly just because it's shiny.
As far as I know Figma used asm.js (then WASM) from the start. I actually don't think they'd have had the success they had without it - it would have been too slow built in JS.
So in a way webasm/asm.js is already allowing whole new categories of webapps we take for granted now.
I always wonder how much faster JS could be if the effort that went into WASM went into JS. ASM.js, SIMD, snapshots, etc directly in JS could have really made it a serious contender for high-performance software.
Of course, without WASM, we'd be missing out on lots of cool software that was previously stuck on desktop/native. But I'm not entirely convinced it was the right path.
They did try to do SIMD in JS, and the proposal made it as far as being implemented in browsers, but it ended up being hideously convoluted in practice so it was killed in favor of WASM SIMD.
The MVP implementation of SIMD.js grew to about 10% of V8s entire codebase, just for the bare minimum "it runs" support without optimisations.
Ballparking it based on the relative LOC of v8/src and v8/src/wasm, about 8%. That's for everything WASM though, not just the SIMD support, and it's a fully optimized and production-ready implementation.
JS being abused as a compilation target is definitely not a long-term strategy for the web. Going forward we need less emphasis on JS and more on HTML and WASM.
> Of course, without WASM, we'd be missing out on lots of cool software that was previously stuck on desktop/native.
Maybe not. Someone could have written a backend for GCC and/or LLVM that targets JS in the same way that Emscripten targets WASM (with JS around the edges).
No there's no announcements yet for #3. But if you look around their code you'll find wasm files for spellchecking/proofing and associated models for select few languages.
Combined with the fact that google docs support proofing for those languages offline, it's easy to guess how they achieved it.
Microsoft Flight Simulator also uses WASM for plugins, which allows them to run portably on both the PC and Xbox versions of the game, with sandboxing, and still get decent performance.
I do wonder why this use case - using wasm as cross-platform, cross-architecture portable binaries with performance profile "close enough" to optimized native code - is not more common. One can easily imagine an OS directly supporting such binaries even, JIT-compiling and caching them as needed.
Reminds me of the commercial of the old auntie using her wall for offline Facebook with her friend pointing and confusedly declaring "That's not how any of this works!"
I'm developing a wasm game, and currently I am targeting WebGL2 in order to run in iOS Safari.
Me (and others, I'm sure) are currently waiting for WebGPU [1] to land in Safari so it will make sense to target it.
WebGPU allows for simplified porting of desktop games to the web, such as WGSL shaders [2]
WebGPU will be the next big thing [3], and currently it is enabled on Chrome Windows/macOS, and can be enabled in Firefox Nightly with a config setting.
There's also an issue with limited language support. For example golang still has some stuff left to stabilize around the WASI, and the resulting binaries are rather large.
In rust, things look better. I can compile a release of my game to about 8MB .wasm file, which gzipped sits at around 3MB. Most other tooling I have looked at produces far larger wasm binaries, which makes it a no-go for mobile apps.
8MB seems high for Rust. Even the project I did [1] which was using D (with GC) ended up with an 8MB WASM. Rust's WASM target is much more exercised than D's, so I think you might need to tweak some compile options.
I agree that 8MB seems high. I can generate a 6MB binary using `--debug` with `wasm-pack` so definitely for a more complex thing I could see 8MB. I think `--release`, `codegen-units = 1`, `opt-level = 3/z` are the three biggest things that affect binary size for me.
I don't think 8MB is that big a deal for a web game though. Like how large are the images? If you're going to dynamically load in like 50+ MB of assets then having an initial game of 8 MB is the small pole in the tent. I have my stuff setup as a PWA so once everything has been downloaded it takes 0 MB on the wire to open a second time; you could set-up the game as 2 binaries; one super-small one that just basically handles an opening cinematic and a larger one that can actually play the game which is downloaded while the cinematic plays (or is cached in future opens).
1. It's too damn hard to get data into and out of wasm modules. The component model is addressing this but it's sprawled out into literally rebuilding "worlds" and turning wasm modules into sort of lightweight virtual machines. I wish there was just more of a focus on getting data into and out of modules first.
2. Lack of GC which has made languages like js/python/jvm/c# unfeasible. WASM GC is just now available and hopefully ship compilers can target and build wasm modules that aren't so large in not too distant future.
Once we are past these 2 items, wasm can run free and really should become the final unit of deployment.
edit: I also suspect that like the jvm which started as a client tech, wasm will find more use on the server side, than on the client side in info/business type software.
> The component model is addressing this but it's sprawled out into literally rebuilding "worlds" and turning wasm modules into sort of lightweight virtual machines. I wish there was just more of a focus on getting data into and out of modules first.
As someone who works on the Component Model, this perception is interesting to me, can you explain your thinking a bit more? From my perspective, getting data in and out of modules is indeed solved. Worlds are a type signature that describe what datatypes and methods are available in a particular embedding, with standards for command line and http proxies, but easy to define whatever your situation requires.
As someone who wanted to try to use WASM ~1yr ago, I was unable to find any reasonable way to get data in/out of wasm from the local environment, and gave up on trying to learn it because of this.
Could you please provide links/info for how to do so? I want to be able to learn how to use it, but without this ability it seems entirely useless for me.
Yep, this is one of the initial motivations for creating Extism: https://github.com/extism/extism -- and it works across 16 host languages & 8 guest languages.
Sadly the current iteration of WASM GC is still too limited for stuff like JVM or C# garbage collection semantics without jumping through a lot of hoops. I'm optimistic that in a few years there will be an expanded version of it that more runtimes can adopt, though.
#1 is a pet grievance of mine though. The intentional choice not to build mmap or read-only pages into the WASM memory model is really frustrating.
I've been wondering how WASM GC works with multiple wasm modules, it sounds like you might know. Does WASM GC exist outside individual modules managing memory for many, or is it "contained" inside each module? Does it allow for efficient sharing and minimal copies of memory between modules when host calls both?
For example say you have some data like (eg. string "abc123") in host memory and then pass into module A which then reads/operates the data, and then returns some other data to the host. The host then calls into module B passing the original host data and data returned from call to module A. Can that original host data be shared efficiently and managed by WASM GC between modules?
I'm not aware of any reason why what you're describing wouldn't work. At least in a browser tab, all the wasm modules will share the same JavaScript GC heap, so the string data should be sharable between the modules if it's passed around as a GC reference.
Are you referring to the weak references or to interior pointers? What I've been surprised by over the years it that a simplified, perhaps slightly broken version of a language comes to Wasm first, then as features expand, more of the guest language features, libraries, platform, and ecosystem comes, piece by piece. CheerpJ claims to have a fully-featured JVM, and Google is fielding Java compiled to Wasm GC with pretty good results. Wasm is bringing these platforms over piece by piece; so far there haven't been few "boom, here's full Language X on Wasm" moments. Instead we're progressing quite incrementally.
Interior pointers and WRs are both basically mandatory, yeah. I have faith they'll arrive eventually.
I think incremental progress is generally great, but since we already have 'all of .NET' in WASM by shipping our own GC, end users seem like they wouldn't be happy with 'we use WASM GC now and all of your code is broken'
EDIT: We also have dependent handles in a few places, and I'm not sure how you'd do those without a more sophisticated GC. But it's probably possible and they're at least not used as widely as WRs.
Quite a bit of code may end up relying on a CWT because a dependency uses assembly-unloading-friendly cache internally, hopefully it fails gracefully once .NET switches to WASM GC...
I bet it is used in a lot of ways people don't notice. In my site[1] I use wasm to run an ancient piece of code called SGP4 to propagate satellite orbits, but it's totally invisible to the user. Someone actually ported SGP4 to JavaScript but it's slower and the results don't perfectly match the original, so it's great to have the option to run the real C version (actually the original is Fortran but the C port is the standard these days).
Ah, I used your site a lot after I bought a beginner's telescope some years ago, thanks for all the fun I had waking up early to spot satellites! Had no idea it had any wasm, interesting!
I sunk a decent amount of time into WebAssembly over the past few months (I am the author of "watlings").
From my understanding, there are 3 answers here.
1. Most spaces do not need WASM. You don't necessarily see speed improvements since usually your JS and WASM (in the browser) are compiled into the same thing.
2. WASM is very good at bringing tools to new spaces. The biggest limitation here is in both tooling and education. It is not trivial to compile something like FFMPEG for the browser. Improvements to the WASI standard are helping here.
3. WASM is starting to see use in different spaces. For example, as a containerization format for efficient sandboxing.
> 2. WASM is very good at bringing tools to new spaces.
Yeah, I agree with this. I have a few ongoing fresh-start projects that are being built with WASM as the primary build target. And like you said, the tooling is definitely not great. Plus the load times for some wasm binaries are pretty slow.
There are usages outside of the browser too. We are using wasm as a runtime for applications and modules deployed in small IoT device. Wasm helps overcome the typical limitations of those devices giving platform independence, sandboxed environments, ability to verify and sign modules ahead of deployment, allows developers to program in dominant languages and compile to wasm, and still retain a low footprint which is critical in this context.
Sometime back I did some experiments with WASM over ESP32 board[1]. It was fairly easy to get a simple WASM program to work, though there was a fair amount of (ongoing) work left to bring it into usable shape.
I think there's a lot of inertia with the JavaScript-based systems and WASM represents a certain upheaval to that model. I have been toying with Blazor WASM recently though and to be honest, so far my experience has been very good, including debugging. I think WASM will grow quiet adoption over time, particularly for business apps.
It solves a problem that most web developers don't have: running performant code in the browser. It cant manipulate the DOM natively and so most developers have no use for it.
Additionally, the kind of developers who would like to be able to write C/C++ or other compiled languages in the browser are not usually web developers; most of the frontend developers I know are highly specialized in their frameworks or fields. They rarely, if ever, venture outside of frontend development and the kinds of technologies they need are not high performance WASM code but type safe and runtime negligible typescript code
WASM is a technology for software engineers to be able to target their programs for running in the browser, not a technology meant to make frontend developer lives easier
> WASM is a technology for software engineers to be able to target their programs for running in the browser, not a technology meant to make frontend developer lives easier
Writing as one of those people trying to make my programs run in the browser, the most painless way still seems to be "write it in js/ts." Which sucks. Doubly so if it's something I have already written in my language of choice, and triply so if it contains dependencies I didn't write. And that's practically every project I've wanted to run in the browser.
Yeah the problems it is meant to solve are not problems that most frontend developers have. Frontend developers are often constrained by development time and maintainability, not performance. Frontend developers care about expressing their code in the most succinct and maintainable way: how can I do something with the least amount of boilerplate possible? That's why we have frameworks: to standardize common patterns in web development and cut down on the amount of time required to build an application. Most frontend developers are not working on performance-heavy applications that require WASM, they're working on forms which get POST'd directly to an API somewhere that does all the real heavy lifting (or just serves as a CRUD interface to a database)
"Since only numeric values can be exchanged between the WASM module and the JS host, any JS native objects the WASM side might want to be working with must be managed manually in JS. "
At the moment you need to send state between WebAssembly and JS contexts in order to manipulate the DOM.
> By itself, WebAssembly cannot currently directly access the DOM; it can only call JavaScript, passing in integer and floating point primitive data types. Thus, to access any Web API, WebAssembly needs to call out to JavaScript, which then makes the Web API call. Emscripten therefore creates the HTML and JavaScript glue code needed to achieve this.
> Note: There are future plans to allow WebAssembly to call Web APIs directly.
This is no longer true, there's various high level types that WebAssembly can pass around, such as reference types (opaque objects from the outside world, i.e. JavaScript objects) and all the new GC types. So the only thing stopping you from calling into web APIs is importing them into the WebAssembly, which atm is indeed still a manual process (or automated with some codegen).
Allowing WASM to call various Web APIs should be interesting and open up more possibilities and applications, although I can see it becoming more of a security concern as well.
The document links to a repository talking about garbage collection, but I couldn't find where they're discussing opening up to Web APIs. Any ideas anyone?
From one perspective, it's a big success in that it's deployed "everywhere", has multiple implementations, and seems to work the same way everywhere. Many language toolchains target it, although there are varying degrees of success / performnance.
From another perspective, it's a "failure" because it's not the end of JavaScript, and it's not an operating system.
There were a number of people/organizations promoting as such -- saying it's basically going to take over all of computing, and be both the foundation of all languages and the foundation of operating systems. That seems a bit silly.
WebAssembly can be used to reuse logic between web, mobile and desktop apps. For example you can write your core logic once in Rust and then make a native UI for different platforms. We've used this approach for Koofr Vault [1] (client side encrypted cloud storage) and we couldn't be happier. Rust for core logic, React for web and desktop apps (with Tauri), SwiftUI for iOS and Jetpack Compose for Android.
Some things that might greatly increase wasm usage and overall tooling:
1) Tools that run docker containers and serverless function services (like AWS lambda) to support providing a .wasm files instead
2) Garbage collection in the runtime to make GC languages easier to port to wasm
3) Dynamically typed languages (NodeJS, Python, Ruby) being able to compile to webassembly directly instead of porting the runtime to webassembly and then running the code through the runtime. This is a big ask though, basically needs to redesign the runtime completely
4) wasm-DOM bindings will enable other languages to do HTML rendering which will require new web frameworks for every language that wants to take over the space from JS. This will lead to (even more) fragmentation of the web ecosystem
5) A new wasm-first SDK (unrelated to the DOM) for building cross platform applications. I can see this taking off only if it is built-into the browsers and backed by some standards committee, so not very likely I think
6) Something like the Interface Types proposal ( https://github.com/WebAssembly/interface-types/blob/main/pro... ) becomes a thing allowing wasm programs to be consisted of modules written in several different languages and being able to call said modules with low or 0 runtime performance hit (and of course, no compilation to multiple CPU archs). So much of programming ecosystems are locked to specific languages (like data science with python) when there is little technical reason for it be like that.
Besides the other comments here, currently its mostly:
* wasm64: allowing more than 4gb RAM usage
* wasm virtual memory: allowing real memory allocation/freeing from wasm outside of the monolithic memory model
Both of these things are necessary for many complicated applications to run inside the browser seamlessly at high performance, both of these things have been on the WASM horizon for years and have made little or no progress.
I feel like some elements in the WebAssembly committee try to actively hinder sane JS integration. Once we can use wasm gc objects in js and js objects including strings in wasm (without gluecode hell) adoptation might skyrocket.
GC strings worked for a while in Chrome, but the "test has ended"
This matters not just because of aesthetics but glue code removes the potential speed advantages of wasm.
Do you have any stats from which you know that adoption is limited? The thing is, you won't necessarily know if an app is using it unless you're deliberately checking the sources in the dev console, so there could be a lot of sites that you're using that have wasm running in your browser without your knowledge.
That being said, one thing that's potentially holding back developer adoption is that, in its current state, wasm is best suited to low-overhead languages like C, C++ and Rust. And then there's the fact that most of the code that runs in the browser is UI code, and it'd be hard to justify writing your frontend in Ruby or Python, which would mean that the browser download a big wasm blob just to write your code, worse performance than JS once it starts running, and a much less stable ecosystem.
Not sure if WASM is there yet, but maybe the crud app can be built using a programming language that the developer prefers? Like Java, C#, Go, Rust, C++, whatever instead of JavaScript/TypeScript?
Yeah, we took a bet that writing our compiler, simulator, etc. in Rust and architecting correctly so it could compile to native and WASM would let us run native and in the browser too, and we’re pretty thrilled with how it turned out.
I'm currently taking the same route with my compiler. It's written with extreme efficiency in mind, so I'm planning to expose a client-side WASM binary on the main site, that will let you interactively explore the language with low latency.
This is a great use case of WASM, I think. Language compilers/interpreters/runtimes to be compiled to WASM so they can run on the web, enabling interactive code blocks, playgrounds, or integration with web-based code editor and IDE. That lowers the barrier to entry, so a beginner (or seasoned user) can simply visit a web page and start playing with running code - instead of having to install anything on their local machine.
Have you considered an open source the parser/compiler framework that targets wasm? I suspect that dsl's and tiny languages compiled directly to wasm could be valuable.
I think most web pages do not need such features. WebAssembly has seen lots of adoption on the websites that do, like Figma and Photoshop for design, Zoom and Meet for interactive video, Unity for games, etc. etc. But most web pages are just text, and that's fine.
Wasm was never intended to be used on every web page, just like the Video element wasn't.
Surely you mean WebCodecs rather than WebGL/WebGPU? AFAIK no encoding primitives are exposed by WebGL/WebGPU.
The advantage of shipping an encoder in WebAssembly for is that you don’t have to rely on the browser supporting the specific codec you want. e.g. Safari and Firefox don’t yet support WebCodecs at all, but do support WebAssembly.
I didn’t realize enough of the work in decoding mpeg was paralellizable enough to do on the GPU, let alone in the constrained world of WebGL, but apparently it is.
it's maybe negligible compared to the code-size bloat of web applications, but delivering large libraries over the network with only limited caching is less than ideal
Around a year ago I used the GHC WebAssembly backend to get some Haskell code running in the browser, but that needed WASI(WebAssembly System Interface) which was tricky to set up correctly. There were plenty of warnings about things being incomplete and experimental, and the code would crash unless I told it to do some pointless work during initialization (my best guess is that there was some bug involving the Haskell garbage collector and memory allocation - there are enough warning messages that I don't think "it's never a compiler bug" applies here).
> Question from someone knew very little in this domain: what stops mass adoption of WebAssembly?
I think it's the focus on native apps. There's isn't exactly a benefit of WASM when you have a native app.
I was kinda hoping all the complaints about app stores would push people back to web apps and then I think you'd see a surgence of WASM. I guess Apple/Google gives apps too much tracking ability on native apps compared to web apps to make it worth it to re-do the app thrice (Android/iOS/Web Desktop) instead of just twice (Mobile Web/ Desktop Web).
From what I understand, it’s still pretty clunky to do multithreading with it. So people who want the speed of near native execution often also want extra threads.
- CPU features and system calls. Native code can leverage specific CPU features to gain performance. It has access to files and the network via OS system calls. Code compiled to WASM runs inside the WASM sandbox. It makes code slower. Getting data to/from the WASM code is harder.
- The WASM engine is right next to a “good enough” alternative (JS).
Yeah, Mozilla and the Chrome team were pushing a lot for it, and spent a lot of engineering effort on it. So far it seems a strategic failure, both for Mozilla which couldn't afford such diversion of ressources, and for the Chrome team after NaCl's retirement.
There are a lot of projects around WebAssembly. But technology is hidden from external view. (Some self promotion, I am creating https://exaequos.com, a new Unix like OS running in a web browser)
In my job we are using duckdb compiled to wasm in our browser-based application. We store time series data in it and can query the data to show charts and logs using SQL.
We insert the data into the database as we collect it, then we query the database for showing charts with the query parameters (time-range, parameters to plot, etc) based on the UI controllers. We also use its built-in parquet export functionality. It works great.
Is the site working? There seem to be broken sections: a section that just says "undefined", a large section that's blank, and a section that just says "Error: process exited with code 1.".
You may need to wait for a while till the wasm file is loaded, and there is a chance that the disassembly or execution result is not shown. In that case, please try to run the code block again.
A few years ago, I used a WASM demo website which can use a WASM version of ffmpeg to mux audio and video into a file (transcoding obviously wasn't practical, at least not at that time), and I was very impressed. I can see lots of potential of it.
But I still haven't see much usage of it even today.
(To be totally honest -- i'd rather it's not popular because it would make debugging websites/web applications close to impossible; but that's besides the point.)