logoalt Hacker News

pjmlpyesterday at 10:47 AM2 repliesview on HN

Tooling is holding back WebAssembly.

It is very hard to debug WebAssembly applications, depending on the source language, we are still on printf debugging kind of experience.

Even the DWARF plugin for Chrome (only, nowhere else), hasn't been updated since 2023.

Then there is the whole experience, again depending on the language, to produce a .wasm file, alongside the set of imports/exports for the functions, instead of a plain "-arch=wasm".

GC support is now available, however it is a "yes but", because it doesn't support all kinds of GC requirements, thus some ecosystems like .NET, still need to ship their own.

Finally we have WIT trying to be yet another go at COM/CORBA/gRPC.


Replies

valadaptiveyesterday at 12:05 PM

I second this; the tooling is somehow still not there after 10 years.

- The main toolchain for compiling existing C codebases to WebAssembly is Emscripten. It still hasn't escaped its tech-demo origins, and it's a rats' nest of compiler flags and janky polyfills. There are at least 3 half-finished implementations of everything. It doesn't follow semver, so every point release tends to have some breaking changes.

- The "modern" toolchain, wasi-sdk, is much more barebones. It's getting to the point of being usable, but I can't use it myself because it ships a precompiled libc and libc++ that use `-O3`, whereas Emscripten recompiles and caches the sysroot and uses `-Oz` if I tell it to. This increases the code size, which is already quite large.

- LLVM is still not very good at emitting optimized WebAssembly bytecode.

- Engines are still not very good at compiling WebAssembly bytecode to optimized machine code.

- Debug info, as you mentioned, is a total mess.

- Rust's WebAssembly tooling is on life support. The rustwasm GitHub organization was "sunset" in mid-2025 after years of inactivity.

- There is still no official way to import WebAssembly modules from JavaScript in a cross-platform manner, in the year of our lord 2026. If you're deploying to the browser and using Vite or raw ES modules, you can use `WebAssembly.instantiateStreaming(fetch(new URL('./foo.wasm', import.meta.url)))` and eat the top-level await. Vite recognizes the `new URL('...', import.meta.url)` pattern and will include the asset in the build output, but most other bundlers (e.g. Rollup and esbuild) do not. If you're on Node, you can't do this, because `fetch` does not work for local files. Most people just give up and embed the WebAssembly binary as a huge Base64 string, which increases the filesize by 33% and greatly reduces the compression ratio.

- If you want multithreaded WebAssembly, you need to set the COOP/COEP headers in order to gain access to `SharedArrayBuffer`. GitHub Pages still doesn't let you do this, although it's the third-most-upvoted feature request. There's a janky workaround that installs a service worker. All bets are off on how that workaround interacts with PWAs.

If the tooling situation had advanced past "tech demo" in the past 8 years since WebAssembly first shipped, a lot more people would be using it.

show 1 reply
embedding-shapeyesterday at 12:02 PM

> Then there is the whole experience, again depending on the language, to produce a .wasm file, alongside the set of imports/exports for the functions, instead of a plain "-arch=wasm".

Doesn't the "WASM Components Model" kind of solve this? I've been hacking on a WASM-app runner (in Rust) which basically loads tiny apps that are compiled into "Components", and seems simple enough to me to use and produce those.

show 1 reply