DEV Community

Cover image for The 7 Walls JavaScript Hits — and How WebAssembly Gets Past Them

The 7 Walls JavaScript Hits — and How WebAssembly Gets Past Them

James Anderson on September 28, 2026

Every time Figma renders a complex design instantly, or Google Sheets recalculates a huge spreadsheet without lag, or a Shopify store applies a cus...
Collapse
 
sylwia-lask profile image
Sylwia Laskowska •

Great post! I just want to add that yes, WASM is the default runner for inference in the browser, but the real gains you get come from running it on WebGPU.

Collapse
 
james_anderson_h profile image
James Anderson •

Great addition, and an important clarification — you're right that I compressed those together. Wasm and WebGPU are doing two different jobs in browser inference: Wasm is the portable, runs-everywhere baseline (it'll work on anything, no special hardware assumed), but the serious performance for real model inference comes from WebGPU getting you actual GPU acceleration. The honest framing is that Wasm makes in-browser inference possible and portable, and WebGPU makes it fast — they're complements, not competitors, and a lot of the ONNX Runtime Web / TensorFlow.js setups will use a Wasm backend as the fallback and WebGPU as the fast path when it's available. So "Wasm for inference" is really "Wasm for reach, WebGPU for speed." Good catch — worth making explicit, because someone reading the piece and expecting native-GPU numbers from the Wasm path alone would be disappointed.

Collapse
 
utilvo profile image
utilvo •

Really good 🤝, especially the point that Wasm is more useful when it solves a specific bottleneck rather than being treated as a replacement for JavaScript.

The browser-side use cases are particularly interesting. I've been working on client-side PDF processing recently, and Wasm makes a noticeable difference when you start dealing with parsing, document manipulation, and larger files without sending everything to a backend.

I also agree with the point about not using Wasm everywhere. The boundary between JavaScript for the UI and Wasm for the compute-heavy parts seems to be where it makes the most sense.

Collapse
 
james_anderson_h profile image
James Anderson •

Client-side PDF processing is a perfect example of the pattern — parsing and manipulating large documents is exactly the compute-heavy, keep-it-off-the-backend case where Wasm earns its place, and doing it locally means the files never leave the user's machine, which is a privacy win on top of the speed. And you've landed on the boundary that actually works: JavaScript for the UI, Wasm for the heavy compute. That division is the whole thing — not "replace JS," but "hand JS the parts it's bad at." Thanks for the real-world data point.

Collapse
 
unitbuilds profile image
UnitBuilds •

You can also look into what wasmer did with WASIX, it was their attempt at getting more functionality out of WASI, given it was a bit shallow vs POSIX. I've been really deep diving into it since the interviewing started at them, there's still a few holes, but they're not nearly as big as they used to be. Their sdk set is also quite decent.

The concept of WASM is definitely the future we've been wanting 'run anything, anywhere, at native speeds', in that respect, it's amazing! One of the projects I showcased, was a rust-based MCP server, that supports tools from all the major languages, using WASM and supports dynamic tool registration (no restarts needed) and an audit log for every tool call and full isolation for multi-tenancy. That's all stuff possible with WASM, impossible on Node.js.

That being said, WASM as a platform still needs ALOT of work... Take Wasmer for instance, distributed WASM runtimes across the globe, if the server near you goes down, you're directed to the next server, if 2 people on opposite sides, different servers, edit the same thing at the same time, they havent quite figured out CRDT for it yet (I also showcased it implemented to them). So it needs work... But in the age of AI, expect the WASM platform to grow fast and make up for the years it's behind.

Collapse
 
james_anderson_h profile image
James Anderson •

WASIX is a great pointer — filling in the POSIX gaps WASI left shallow is exactly what's needed for the "run real server apps" story to hold, and it's good to hear from someone deep in it that the holes are shrinking. Your Rust MCP server is the perfect proof of the thesis: tools from any language, dynamic registration with no restarts, an audit log per tool call, full multi-tenant isolation — that combination genuinely is impossible on Node, and it's the untrusted-code + plugin walls made real. And your honesty about the gaps (the distributed-runtime CRDT problem you had to implement yourself) is the credible part — the platform is years behind where the concept promises, but you're right that AI is about to pour rocket fuel on closing that gap. Great data point from inside the ecosystem. 🤝

Collapse
 
unitbuilds profile image
UnitBuilds •

My current hiring assignment is porting pgrust to run in wasmer. Just about done with that. That's where I found alot of things that simply arent ready yet. Not too sure how deep you are into Rust, but unwind panics werent supported, they just aborted as a way to 'make it work' at the time, but I fixed that, so pgrust would actually function properly. A perfect example of how WASM works and the clean separation it brings. You can run pgrust, but can you call it complete, if it cant Error handle properly? That's the tiny holes in WASM as a standard that need filling, cuz an app that works isnt good enough, it has to function identical to native, else there'll be edge cases that break it and a broken web service isnt great... I think (theory, no proof) that their current setup where you can select a database during setup on Wasmer, runs the database outside of wasm, because a database is undeniably the most important part of an app to get right and rather than offering a 'partially right' version, they accepted that the platform needs more maturing first and instead left it running as a separate external service outside of their ephemeral wasm instances, to make sure it persists perfectly, every single time, cuz 1 slip up and it's business data lost/corrupted, not just 'oh the app crashed'.

That kinda makes me confident in where WASM is going, the people behind it know the boundary of what's experimental and what needs to be flawless. Cuz it just takes 1 bad app to make someone reject WASM for the next 5-10 years, so when it's advertised as working, it has to work flawlessly.

Thread Thread
 
james_anderson_h profile image
James Anderson •

Porting pgrust into Wasmer is about the best stress-test of the platform's maturity you could pick, and the panic-unwind detail is the perfect example — an app that runs but aborts instead of unwinding isn't complete, because "works in the happy path" and "handles the error path identically to native" are different bars, and the gap between them is exactly where production breaks. That's the WASM-specific version of a theme I keep circling: working isn't the same as correct, and the edge cases are where the truth lives. Your read on why they run the database outside wasm is sharp and, I think, right — the maturity move is knowing which parts you're allowed to ship "mostly right" and which parts have to be flawless, and a database is squarely the second kind. "The app crashed" is recoverable; "the business data corrupted" ends you. And your last point is the real stakes: WASM only gets one reputation, so shipping the flawless-required parts before they're flawless would poison it for a decade. The fact that the people building it clearly know that boundary is the most reassuring thing in your whole comment. Genuinely great view from inside the work — thank you for it. 🤝

Collapse
 
kenwalger profile image
Ken W Alger •

Really good framing, especially treating Wasm as something you reach for when you hit a particular boundary rather than as a JavaScript replacement.
The untrusted-code and plugin cases are the ones I find most interesting, partly because the sandbox changes the architecture question. Instead of asking “how do I stop this extension from doing things it shouldn't?”, you can start from “what capabilities is this extension actually entitled to have?”
That sounds like a small distinction, but it moves authority from convention into the execution boundary. Filesystem, network, host functions, credentials, etc. aren't ambient capabilities the plugin promises not to misuse. They're things the host has to deliberately provide.
I do wonder where the sharp edges move, though. Once the Wasm module is isolated, the host interface becomes the interesting trust boundary. A perfectly sandboxed module with an overly generous set of host capabilities is still overly privileged.
So perhaps there's an eighth wall hiding in the plugin/untrusted-code sections: not just “Can I run code I don't trust?” but “Can I make what that code is allowed to do explicit and inspectable?”
That's a capability I suspect becomes increasingly useful as more of the code we're asked to execute wasn't written by us in the first place.

Collapse
 
kyisaiah47 profile image
Isaiah Kim •

How did you measure startup time across the two runtimes, and did the Wasm result include compilation?

Collapse
 
technogamerz profile image
𝐓𝐡𝐞 𝐋𝐚𝐳𝐲 𝐆𝐢𝐫𝐥 •

Really very very nice!! ❤️🙂