Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
Running WASI binaries from your HTML using Web Components (runno.dev)
165 points by benno128 on Aug 27, 2023 | hide | past | favorite | 72 comments


Very slick and opens up so many possibilities.

WebAssembly, WASI, like WebRTC/WebGPU/WebXR/WebAudio, just makes webdev, gamedev + native/networking very very interesting in this phase of technology where js frameworks are culty bloated/verbose and apps are the main thing for marketing/tools. Web apps + tools are opening up with wasm/wasi.

Runno (https://runno.dev/ + https://runno.dev/wasi) is a great idea and helps make interesting native stuff in a sandbox locally. Running all this directly without having to mash into assembly is a great idea. Awesome job on this!

> Runno helps you make runnable code examples that can be embedded in web pages. This is very handy for educational tools, it means:

> - You can make code examples that don't need users to install scary tools.

> - No need to run a server, it all runs client-side in the browser.

> - Your users can edit and re-run any code examples you make.

> - The examples are extremely customisable with HTML, CSS and JavaScript!


Yet I am still waiting to see a game with the same capabilities of Infinity Blade, that Apple used in 2011, as an example of a game showing of the newly acquired OpenGL ES 3.0 capabilities of iDevices.

Or the Unreal Engine 3.0 citadel demo, also in 2011, for Flash/CrossBridge.

It seems the only thing usable is running ShaderToy demos, and 3D views on ecommerce sites.


That expectation is off by nearly a decade. WASM games in terms of performance are closer to 2000 than 2010. Here's an open source indie game from 2003 that I ported to WASM [1]. It struggles to hit 60 FPS on devices that were released a good 15 years after the game itself. Browsers sometimes struggle to animate simple lines at 60 FPS still to this day, because they're just hugely massive platforms with thousands of moving parts with no room for big, complex apps on top of them.

[1] https://neverball.github.io/


Glancing at the project, one area where things could go terribly wrong is the translation layer from GL 1.x to WebGL. For instance 'tricks' that are common on native GL implementations like buffer orphaning are actually harmful on WebGL and may cause lock stalls which would cause exactly the issues you describe (e.g. struggling to hit a consistent frame rate despite extremely low CPU and GPU load).

Even though WebGL and WebGL2 are implementations of the GLES2 and GLES3 APIs you usually can't just take a non-trivial GLES2/3 code base and expect it to work without hickups on WebGL, what's going on under the hood is just too different.


A couple of years back I also wrote a pure WebGL renderer for Neverball levels [1]. No physics, no translation to WebGL, just the 3D renderer part in direct WebGL. It also has a surprisingly low performance ceiling. I'd say I managed even worse than what the gl4es translation layer does for Neverball. By far the biggest performance boosts were instanced arrays and vertex array objects - basically just reducing the number of calls into WebGL. Seems to me that WebGL has a lot of overhead with or without a translation layer.

[1] https://github.com/parasti/parabola


I did some GL benchmarking for simple draw calls (on desktop) a couple of years ago, and while it's true that WebGL came out lowest, the difference between native drivers were much bigger. I basically checked how many trivial draw calls (16 bytes uniform update + draw call) were needed on Windows before the frame rate drops below 60 fps, and for WebGL in Chrome this was around 5k, Intel native was around 13k, and NVIDIA topped out at arond 150k (not all that surprising, since NVIDIA has traditionally the best GL drivers).

It is definitely true though that you need to employ old-school batching tricks to get any sort of performance out of WebGL, but that's also not surprising, because WebGL is only a GL by name, internally it works entirely different (for instance on Windows, WebGL implementations are backed by D3D).


If we hadn't lost a decade with what Flash and PNACL already offered us in 2011...

No wonder studios rather bet on streaming than a tech that will never deliver.


Let's be clear what Flash was though. It was a native binary that would paint to a region owned by the browser. So yes, it was performant because basically the only thing it was doing differently than any other native application was how it was hosted by the browser.

That's also why it was such a security nightmare. It was a complete escape from the browser sandbox.


It was a great development experience, destroyed by pitch forks and lanterns by the folks that a decade later have failed to deliver a sound alternative.

Hence why the gaming industry is focusing on streaming instead.


Flash was destroyed by Apple, which had no interest in improving the web either. The iOS platform turned out to be a pretty good replacement for Flash though.


Apparently people keep forgetting that after that memo, Adobe produced an AOT compiler for Flash, targeting iOS.


Sure, but what's the point if it's not supported by Safari. Adobe Air was at best a porting aid to get your old Flash code wrapped in an iOS app, but the writing was on the wall and nobody in their right mind would start new Flash projects.


And now a decade later, despite PlayCanvas and Babylonjs, there is hardly anything that compares.

Mobile, handhelds and cloud streaming, is where the indie party is going on.

I bet WebGPU is going to be equally the same, ShaderToy and 3D commerce visualisation tools will be updated for it, and that is it.

Specially given that it made the same mistake of WebGL, lagging 10 years behind native APIs.


PNaCl was a joke though, it suffered from much longer client-side compilation times than both asm.js and WASM ever had, and performance was at most on par with asm.js.

(NaCl was better in those areas, but required to stamp out one binary for each target CPU architecture)


A joke that was able to deliver more than WASM/WebGL have yet to deliver.


A browser also has the baked in expectation of you interacting with hypertext.

A video game of this caliber you are discussing is typically entitled to:

- have a dowload and installation process that might span over say 20min or more

- load slowly, because it needs to push a ton of assets through

- demand a ton of resources such CPU, GPU, threads, memory etc. to achieve amazing graphics and simulation

- being the primary foreground process or possibly the only one

None of these things apply to the typical web. Quite the contrary: most web devs would get fired or ridiculed if they demanded these resources.

So I assume that browsers optimize for the typical usage, which is hypertext.


Problems that can be sorted out, if there was any industry interest.

As it stands, everyone is going with cloud streaming instead.

Still uses a browser.


There's definitely something strange going on here. I'm getting about 3x as much CPU load on the WASM version as compared to native. Still low enough for a solid 144fps on my machine, but there shouldn't be this much overhead.


The number of calls needs to be lower for a WebGL application. You have to use as much instancing as possible. The security layer makes the calls the slowest part of the pipeline. That's why you see amazing things in shadertoy. When the whole shebang is in the shader it runs smooth.


I need to double check what you're saying, how do you show the FPS in your WASM port?


Devtools or F9 while in game. Type a famous magic word in the title screen to access all levels. Not sure how to do this on a phone which is what I was referring to - but framedrops are pretty obvious.


I've done a quick test and it runs very smoothly on my original OnePlus One from 2014 (so 11 years after the game). This is on latest Chrome, Android 11 (LineageOS 18.1).

I still find it amazing that this game never made with this in mind, the web tech at the time on the OnePlus One was nowhere near able to run this in browser and it works perfectly today!


To be fair my reference browser is Firefox, WebGL is a fair bit slower there.

What blows my mind with this technology is little things: porting the game to the browser gave me a half-working mobile port basically for free (had to implement touch input handling in Neverball). On top of that, thanks to SDL2 and the game controller web API, I can attach a game controller to my phone and play the game in the browser on my phone with a game controller. It just seems unreal that this combination of technology just works.


Thanks, I suspect it might be gl4es but I need to find my old phone to investigate. Magic word is "xyzzy" for anyone else looking.


Apple has been slowing down WebGL I think. See eg people complaining in https://developer.apple.com/forums/thread/696821 and https://discourse.threejs.org/t/horrible-3d-three-js-perform...


80% of the browser mobile market belongs to Google, plenty of customers, even better when looking at the desktop market.

Usually a good excuse why the tech doesn't get uptake.


The unreal citadel demo was running in a browser without flash in 2014: https://blog.mozilla.org/en/mozilla/mozilla-and-epic-preview...


3 years to catch up with 2011 tech, and a decade later nothing better to show.


My hypothesis is that monetization on the web is harder so there are not as many resources spent on games in browsers. If anyone is willing to spend a lot of time on the game they are probably willing to install it, people arent conditioned to pay up front for websites, the UX around microtransactions isn't at all smooth.


These are mostly business issues. If the business problems would be solved, the games would be built, despite any technical limitations of the web platform (which are not much different than limitations on low-end Android mobile devices).

Nobody has figured out so far how to make money with high quality games on the "open web" to get the same return on investment like simple ad-driven 2D games running on closed platforms like Facebook which can technically be cobbled together by 3 dudes in their mom's basemement (exaggerating a bit here of course).

E.g. no matter how you approach it, the Citadel demo wouldn't have led to a web game that would make the same profit relative to the development cost like a simple ad-driven Tetris style game.


No they aren't, at least low end Android devices support GL ES 3.2 and have proper debugging tools.

After a decade Web 3D keeps having spectorJS as the only alternative.

Naturally there are also some masochists that enjoy debugging the browser 3D stack on RenderDoc, while trying to figure out what belongs to their application.


If you use WASM+WebGL, you'd typically debug a native build outside the browser.

According to here GLES3.2 support on Android is currently sitting at 80%, while with GLES3.0 you would reach about 95%, and with GLES2 100%.

https://developer.android.com/about/dashboards#OpenGL

If I would try to ship a native app on Android I would still at least try to only use GLES3.0 features to get that extra 15%.

You enthusiastic charactization of Android debugging tools isn't exactly how I would describe the situation ;)


A kludge to work around lack of tooling for the past decade, and when doing that, no need to WASM anyway.

Even if we consider GL ES 3.0, native comes out winning, due to missing features on WebGL 2.0.

Not only has Android the GPU debugger from Google, that beats anything available for Web, each mobile GPU vendor has their own set of graphical debuggers.


G’day, if anyone has any questions about this I’m happy to answer them here.


What a novel way to integrate a bunch of web technologies! It makes me much more interested in using WASM.


I can imagine how a new style of web-only terminals be possible. The filesystem is realistically _any_ url, and you can load any wasi programs (via a shell, which is also just another wasi program).

I wonder if this is practical, or just a gimmicky way to use a computer...


Thanks! Yeah WebAssembly has an exciting future ahead of it.


I tried this in your Python example:

    import sqlite3
    >>> db = sqlite3.connect("data.db")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    sqlite3.OperationalError: unable to open database file
Presumably that operation failed because there isn't a writable virtual filesystem. Would it be possible to provide one?


You just need to create the file first!

    >>> open("data.db", "w+").close()
    >>> db = sqlite3.connect("/data.db")
    >>> db
    <sqlite3.Connection object at 0x8b3fd8>


Oh cool!

Regular Python doesn't need me to create the file first, I wonder why this works differently.


Might be this particular build of Python, or might be that I implemented one of the `fd` functions in a way Python/SQlite is surprised by. I'll have a look into it some time!


Maybe just the missing leading slash in the original reproducer? :)


Hi, I already support typescript execution in http://chatcraft.org/ via wasm esbuild.

Runno is really cool as it will also lets me support intepreted languages like Python and maybe even golang(assuming i can have a wasi binary produce another wasi binary).

From docs: Currently @runno/wasi supports running only unstable and snapshot-preview1 WASI binaries. The snapshot-preview1 standard is more recent, and preferred.

Where does one see what's part of snapshot-preview1? My google-foo is failing me.


Snapshot Preview 1 is the standard all tools are building to right now. The specification is available here: https://github.com/WebAssembly/WASI/blob/main/legacy/preview...

It's pretty unreadable though!

Preview 2 looks like it will be a big change, and is just being finalised at the moment. I'd expect that when preview 2 is available there will be an improvement in the quality of documentation. I'm not sure how long it will take after release for tools to start switching to it. I'd expect Preview 1 will still be the main target at least for the rest of this year.


Unfortunately this page doesn't load in Firefox on Linux


Also just tested in Chromium, doesn't seem to work for me on Fedora Linux. Just locks up the browser


Would it be practical to output HTML from these WASI components and build a page from them?


I wouldn't put it in prod, but it would be possible. You'd need a JS binding layer that dealt with the output and wrote it to the page, but it could be minimal.

There are other projects that are targeted more at this kind of thing if you want dynamic access to the DOM from Web Assembly (sorry I don't know them off the top of my head).


no questions, hope you're having a good day, cool idea!


Haha thanks, you too!


Hello, thank you for this work as it shows great creative potential.

A suggestion for runno's website, though : when I clicked on the link posted on HN, I did not expect to download that much data. Maybe you could find a way to offer pre-rendered examples and give the user who visits your site a (very visible) option to really download and run things ?


Thanks for the feedback! It’s also cost me about $15 so far. I don’t think I’ll do that again, but it was fun as a demo!


This is seriously awesome. I'm gonna use it in my blog. Stay tuned!


Looking forward to it!


Great stuff.

Is it possible to output to markup from these programs ?

It would be cool if python wsgi programs in this could work somehow.


Yeah of course! They've got STDIN/STDOUT/STDERR and I've built a Virtual Filesystem. But if you're using WASI binaries locally they don't have that restriction.

You might be interested in WAGI: https://github.com/deislabs/wagi

And to catch up on WASI: https://xeiaso.net/talks/unix-philosophy-logical-extreme-was...


I get "Runno crashed: ReferenceError: SharedArrayBuffer is not defined" in every component.


Is this on the blog post, or are you trying it out yourself?

If it's on the blog post, it sounds like your browser doesn't support `SharedArrayBuffer` (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...) or you've disabled Cross Origin Isolation somehow. It might be because you have an old browser (there was a period where it was disabled) or you have disabled Cross Origin Isolation yourself (maybe a security setting?).


Same here - using mobile chromium on android.


SharedArrayBuffer was affected by Spectre vuln and was disabled in some old browsers (or browser config).


It is a nice proof-of-concept, but a pity that runno uses firebase. Any software with built-in SaaS services from advertisement agencies are a no-go area for me.


not loading even after 5 minutes. Firefox latest version here (116.0.3 - 64bit)


website not loading for me


It's a bit temperamental on some browsers sorry (I've seen it fail on Arc). I implemented my own front-end router and I have done a bad job. I've seen it work today on Chrome, Firefox and Safari.


Why is it temperamental? When you say frontend router do you mean in the SPA sense (eg, React/Angular) or do you mean like your own load balancer (eg ALB/HaProxy/Nginx)?

(Not working in Firefox for me)


SPA sense. It’s cobbled together because I just have fun with it. Not sure why it’s temperamental, haven’t bothered investigating.


Not working on chrome here


i tried chrome and safari as well, no luck


Sorry! Sometimes web is hard.


Not loading with Firefox Nightly or Chrome Beta on Linux


Seemed to load, but brought my phone to a crawl (Firefox Android).


Sorry! It is running ffmpeg in your browser on page load, which might not make it happy.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: