I'm definitely excited to see 64 bit as a default part of the spec. A lot of web apps have been heavily restricted by this, in particular any online video editors. We see a bunch of restrictions due to the 32 bit cap today here at Figma. One thing I'm curious though is whether mobile devices will keep their addressable per-tab memory cap the same. It's often OS defined rather than tied to the 32 bit space.
I guess I’m just a crusty ol’ greybeard C++ developer, but it seems like a video editor is out of place in a document browser. There’s a perfectly good native operating system that nobody uses any more.
If we think we need a more thoroughly virtualized machine than traditional operating system processes give us (which I think is obvious), then we should be honest and build a virtualization abstraction that is actually what we want, rather than converting a document reader into a video editor…
> ... document browser ... document reader ...
I'm going to assume you're being sincere. But even the crustiest among us can recognize that the modern purpose for web browsers is not (merely) documents. Chances are, many folks on HN in the last month have booked tickets for a flight or bought a home or a car or watched a cat video using the "document browser".
> If we think we need a more thoroughly virtualized machine than traditional operating system processes give us (which I think is obvious)...
Like ... the WASM virtual machine? What if the WASM virtual machine were the culmination of learning from previous not-quite-good-enough VMs?
WASM -- despite its name -- is not truly bound to the "document" browser.
We have, but not by choice, I miss my native apps, even though ChromeOS Platform pays the bills.
> booked tickets for a flight or bought a home or a car or watched a cat video
Would you install a native app to book a flight? One for each company? Download updates for them every now and then, uninstall them when you run out of disk space etc
I can ask the same question about every other activity we do in these non-native apps.
I have installed all them on the phone, so yes.
Unfortunely several of them are glorified webviews.
I am old enough to have lived through the days Internet meant a set of networking protocols, not ChromeOS Platform.
And on those days hard disks were still bloody expensive, by the way.
> I have installed all them on the phone, so yes.
Isn't your phone providing a sandbox, a distribution system, a set of common runtime services, etc to get these native apps functional?
You don't have to squint your eyes to realize that this thing we call "document browsers" are doing a lot of the same work that Apple/Google are doing with their mobile OSes.
You mean like Windows Store, Mac App Store, apt, yum/dnf, emerge,....?
All the OS frameworks that are available across most operating systems that don't fragment themselves into endless distributions?
Alan Kay on “Should web browsers have stuck to being document viewers?” and a discussion of Smalltalk, HyperCard, NeWS, and HyperLook
https://donhopkins.medium.com/alan-kay-on-should-web-browser...
>Alan Kay answered: “Actually quite the opposite, if “document” means an imitation of old static text media (and later including pictures, and audio and video recordings).”
The problem is: even us old timers can't deny nor change the fact that operating systems have been putting up barriers to disallow running untrusted code downloaded from the internet.
Try to distribute an installer on Windows that isn't signed with an extensive EV-certificate for instance. It's scare popup galore.
Not to mention the closed gardens of the Apple and Google Stores which even when you get in, you can be kicked out again for absolutely no objective reason (they don't even need to tell you why).
> then we should be honest and build a virtualization abstraction that is actually what we want,
This is not in the interest of Microsoft, Google or Apple. They can't put the open web back into the box (yet, anyway), but they will not support any new attempts to create an open software ecosystem on "their" platforms.
Just wait until the Web finally becomes ChromeOS Platform, after the Safari barrier is out of the way.
Personally not a fan of Windows 95 in the browser, however the browser stoped being a “document reader” a decade ago it’s the only universel, sandbox runtime, and everything is moving in that direction ... safe code. WASM isnt a worst VM; it’s a diffrent trade off: portable, fast start, capability scoped compute without shiping a OS. Raw device still have their place (servers). If you need safe distribution + performance thats “good enough” WASM in the browser is going to be the future of client.
A decade ago? Gmail was launched in 2004, 21 years ago.
XMLHttpRequest was part of IE5 in 1999 as an ActiveXObject. Outlook Web team built it a year earlier.
I would argue that as soon as it was decided to include JavaScript runtime in the browser, it stopped being a plain document browser. From then on, we were just on the evolutionary path of converting it from a low capability app sandbox to a highly capable one.
The browser removes the friction of needing to install specialized software locally, which is HUGE when you want people to actually use your software. Figma would have been dead in the water if it wasn't stupidly simple to share a design via a URL to anyone with a computer and an internet connection.
I can't shake the feeling that this ship has sailed and only a few got to get on it while it happened.
And this comes from someone who started with Flash, built actual video editing apps with it, and for the last 25 years build application with "it's not a web app, it's a desktop app that lives in a browser" attitude [1].
Even with Flash we often used hybrid approach where you had two builds from same codebase - a lite version running in the browser and an optional desktop app (AIR) with full functionality. ShareObjects and LocalConnection made this approach extremely feasible as both instances were aware of each other and you could move data and objects between them in real time.
The premise is great, but it was never fully realized - sure you have few outliers like Figma, but building a real "desktop app" in a browser comes with a lot of quirks, and the resulting UX is just terrible in most cases.
[1] just to be clear, there's a huge difference between web page and web app ;D
Think of it like emacs. Browsers are perfectly good operating systems just needing a better way to view the web.
That's too true to be funny!
There are projects to run WASM on bare metal.
I do agree that we tend to run a lot in a web-browser or browser environment though. It seems like a pattern that started as a hack but grew into its own thing through convenience.
It would be interesting to sit down with a small group and figure out exactly what is good/bad about it and design a new thing around the desired pattern that doesn't involve a browser-in-the-loop.
> run WASM on bare metal
Heh, reminds me of those boxes Sun used to make that only ran Java. (I don’t know how far down Java actually went; perhaps it was Solaris for the lower layers now that I think about it…)
The Java went so far down that many early ARM cores could be placed in Jazelle DBX mode, which processed Java bytecode in hardware shudders
I think it was far less special that advertized, so it was probably a stripped Solaris that ran a JRE hoping noone would notice. Dog slow they were at least so from my viewpoint, there was nothing magic about those boxes at all.
With hypervisors and a Linux kernel doing the heavy lifting, the WASM on bare metal probably just looks a lot like a regular process. I would bet Sun did similar … minus the hypervisor.
I do miss the Solaris 10/OpenSolaris tech though. I don’t know anything that comes close to it today.
Solaris is still around, while OpenSolaris forks support Oxide endeavours.
Technically, yes. I built+ported a majority of Debian packages onto Nexenta OS but that effort (and many parallel efforts) just vanished when Oracle purchased Sun. I don't miss SVR4 packages and I never grew fond of IPS. So many open-source folk warned of the dangers of CDDL and they were largely realized in fairly short time. Unsurprisingly, #opensolaris on irc also had a precipitous drop-off around the same time.
dtrace/zones/smf/zfs/iscsi/... and the integration between them all was top notch. One could create a zone, spin up a clone, do some computation, trash the filesystem and then just throw the clone away... in very short time. Also, that whole loop happened without interacting with zfs directly; I know that some of these things have been ported but the ports miss the integration.
eg: zfs on Linux is just a filesystem. zfs on Solaris was the base of a bunch of technology. smf tied much of it together.
eg: dtrace gave you access all the way down to individual read/write operations per disk in a raid-z and all the way up to the top of your application running inside of a zone. One tool with massive reach and very little overhead.
Not much compels me to go back to the ecosystem; I've been burned once already.
But that's what they're doing. The hard part isn't the VM. The hard part is the long fought functional yet secure sandbox that a browser provides.
> functional yet secure
Secure? Debatable. Functional? Not really.
For example, try accessing a security key and watch the fun. Sure, if you access it exactly the way Google wants you to, things kinda-sorta work, sometimes. If you don't want to obey your Google masters, good luck getting your Bluetooth or USB packet to your security key.
And because you are "secure", you can't store anything on the local hard drive. Oh, and you can't send a real network packet either. All you can do is send a supplication request to a network database owned by somebody else that holds your data--"Please, sir, can I have some more?". The fact that this prevents you from exporting your data away from cloud-centered SaaS providers is purely coincidental, I'm sure. </sarcasm>
So in the name of security we just kneecap the end users--if the users can't do anything, they're secure, right? Diana Moon Glampers would be proud.
Plenty of people still want local-first apps that function offline.
Security model of web is needed to be brought to the OS.
I a 64yo fart. Started programming with machine codes. Native is my bread and butter. Still have no problems and am using browser as a deployment platform for some type of applications. Almost each thing has it's own use.
Unfortunately, Memory64 comes with a significant performance penalty because the wasm runtime has to check bounds (which wasn't necessary on 32-bit as the runtime would simply allocate the full 4GB of address space every time).
But if you really need more than 4GB of memory, then sure, go ahead and use it.
The comedy option would be to use the new multi-memory feature to juggle a bunch of 32bit memories instead of a 64bit one, at the cost of your sanity.
didn't we call it 'segmented memory' back in DOS days...?
We call it "pointer compression" now. :)
Seriously though, I’ve been wondering for a while whether I could build a GCC for x86-64 that would have 32-bit (low 4G) pointers (and no REX prefixes) by default and full 64-bit ones with __far or something. (In this episode of Everything Old Is New Again: the Very Large Memory API[1] from Windows NT for Alpha.)
[1] https://devblogs.microsoft.com/oldnewthing/20070801-00/?p=25...
A moderate fraction of the work is already done using:
https://gcc.gnu.org/onlinedocs/gcc/Named-Address-Spaces.html
Unfortunately the obvious `__attribute__((mode(...)))` errors out if anything but the standard pointer-size mode (usually SI or DI) is passed.
Or you may be able to do it based on x32, since your far pointers are likely rare enough that you can do them manually. Especially in C++. I'm pretty sure you can just call "foreign" syscalls if you do it carefully.
6502 zero page instruction vibes.
It was glorious I tell you.
Especially how you could increase the segment value by one or the offset by 16 and you would address the same memory location. Think of the possibilities!
And if you wanted more than 1MB you could just switch memory banks[1] to get access to a different part of memory. Later there was a newfangled alternative[2] where you called some interrupt to swap things around but it wasn't as cool. Though it did allow access to more memory so there was that.
Then virtual mode came along and it's all been downhill from there.
[1]: https://en.wikipedia.org/wiki/Expanded_memory
[2]: https://hackaday.com/2025/05/15/remembering-more-memory-xms-...
> Think of the possibilities!
Schulman’s Unauthorized Windows 95 describes a particularly unhinged one: in the hypervisor of Windows/386 (and subsequently 386 Enhanced Mode in Windows 3.0 and 3.1, as well as the only available mode in 3.11, 95, 98, and Me), a driver could dynamically register upcalls for real-mode guests (within reason), all without either exerting control over the guest’s memory map or forcing the guest to do anything except a simple CALL to access it. The secret was that all the far addresses returned by the registration API referred to the exact same byte in memory, a protected-mode-only instruction whose attempted execution would trap into the hypervisor, and the trap handler would determine which upcall was meant by which of the redundant encodings was used.
And if that’s not unhinged enough for you: the boot code tried to locate the chosen instruction inside the firmware ROM, because that will have to be mapped into the guest memory map anyway. It did have a fallback if that did not work out, but it usually succeeded. This time, the secret (the knowledge of which will not make you happier, this is your final warning) is that the instruction chosen was ARPL, and the encoding of ARPL r/m16, AX starts with 63 hex, also known as the ASCII code of the lowercase letter C. The absolute madmen put the upcall entry point inside the BIOS copyright string.
(Incidentally, the ARPL instruction, “adjust requested privilege level”, is very specific to the 286’s weird don’t-call-it-capability-based segmented architecture... But it’s has a certain cunning to it, like CPU-enforced __user tagging of unprivileged addresses at runtime.)
> The absolute madmen put the upcall entry point inside the BIOS copyright string.
Isn’t that an arbitrary string, though? Presumably AMI and Insyde have different copyright messages, so then what?
And turned out we have the transistors to avoid it, but it's a really good optimization for CPUs nowadays.
At least most people design non-overlaping segments. And I'm not sure wasm would gain anything from it, being a virtual machine instead of real.
wait.... UNREAL MODE!
It looks like memories have to be declared up front, and the memcpy instruction takes the memories to copy between as numeric literals. So I guess you can't use it to allocate dynamic buffers. But maybe you could decide memory 0 = heap and memory 1 = pixel data or something like that?
Honestly you could allocate a new memory for every page :-)
Actually, runtimes often allocate 8GB of address space because WASM has a [base32 + index32] address mode where the effective address could overflow into the 33rd bit.
On x86-64, the start of the linear memory is typically put into one of the two remaining segment registers: GS or FS. Then the code can simply use an address mode such as "GS:[RAX + RCX]" without any additional instructions for addition or bounds-checking.
The irony for me is that it's already slow because of the lack of native 64-bit math. I don't care about the memory space available nearly as much.
Eh? I'm pretty sure it's had 64-bit math for awhile -- i64.add, etc.
They might have meant lack of true 64bit pointers ..? IIRC the chrome wasm runtime used tagged pointers. That comes with an access cost of having to mask off the top bits. I always assumed that was the reason for the 32bit specification in v1
Bounds checking in other PLT is often reproted to result in pretty low overheads. Will be interesting to see some details about how this turns out.
I still don't understand why it's slower to mask to 33 or 34 bit rather than 32. It's all running on 64-bit in the end isn't it? What's so special about 32?
That's because with 32-bit addresses the runtime did not need to do any masking at all. It could allocate a 4GiB area of virtual memory, set up page permissions as appropriate and all memory accesses would be hardware checked without any additional work. Well that, and a special SIGSEGV/SIGBUS handler to generate a trap to the embedder.
With 64-bit addresses, and the requirements for how invalid memory accesses should work, this is no longer possible. AND-masking does not really allow for producing the necessary traps for invalid accesses. So every one now needs some conditional before to validate that this access is in-bounds. The addresses cannot be trivially offset either as they can wrap-around (and/or accidentally hit some other mapping.)
I don't feel this is going to be as big of a problem as one might think in practice.
The biggest contributor to pointer arithmetic is offset reads into pointers: what gets generated for struct field accesses.
The other class of cases are when you're actually doing more general pointer arithmetic - usually scanning across a buffer. These are cases that typically get loop unrolled to some degree by the compiler to improve pipeline efficiency on the CPU.
In the first case, you can avoid the masking entirely by using an unmapped barrier region after the mapped region. So you can guarantee that if pointer `P` is valid, then `P + d` for small d is either valid, or falls into the barrier region.
In the second case, the barrier region approach lets you lift the mask check to the top of the unrolled segment. There's still a cost, but it's spread out over multiple iterations of a loop.
As a last step: if you can prove that you're stepping monotonically through some address space using small increments, then you can guarantee that even if theoretically the "end" of the iteration might step into invalid space, that the incremental stepping is guaranteed to hit the unmapped barrier region before that occurs.
It's a bit more engineering effort on the compiler side.. and you will see some small delta of perf loss, but it would really be only in the extreme cases of hot paths where it should come into play in a meaningful way.
The special part is the "signal handler trick" that is easy to use for 32-bit pointers. You reserve 4GB of memory - all that 32 bits can address - and mark everything above used memory as trapping. Then you can just do normal reads and writes, and the CPU hardware checks out of bounds.
With 64-bit pointers, you can't really reserve all the possible space a pointer might refer to. So you end up doing manual bounds checks.
Hi Alon! It's been a while.
Can't bounds checks be avoided in the vast majority of cases?
See my reply to nagisa above (https://news.ycombinator.com/item?id=45283102). It feels like by using trailing unmapped barrier/guard regions, one should be able to elide almost all bounds checks that occur in the program with a bit of compiler cleverness, and convert them into trap handlers instead.
Hi!
Yeah, certainly compiler smarts can remove many bounds checks (in particular for small deltas, as you mention), hoist them, and so forth. Maybe even most of them in theory?
Still, there are common patterns like pointer-chasing in linked list traversal where you just keep getting an unknown i64 pointer, that you just need to bounds check...
Because CPUs still have instructions that automatically truncate the result of all math operations to 32 bits (and sometimes 8-bit and 16-bit too, though not universally).
To operate on any other size, you need to insert extra instructions to mask addresses to the desired size before they are used.
WASM traps on out-of-bounds accesses (including overflow). Masking addresses would hide that.
Webapps limited by 4GiB memory?
Sounds about right. Guess 512 GiB menory is the minimum to read email nowadays.
I know you're in this for the satire, but it's less about the webapps needing the memory and more about the content - that's why I mentioned video editing webapps.
For video editing, 4GiB of completely uncompressed 1080p video in memory is only 86 frames, or about 3-4 seconds of video. You can certainly optimize this, and it's rare to handle fully uncompressed video, but there are situations where you do need to buffer this into memory. It's why most modern video editing machines are sold with 64-128GB of memory.
In the case of Figma, we have files with over a million layers. If each layer takes 4kb of memory, we're suddenly at the limit even if the webapp is infinitely optimal.
> 4GiB of completely uncompressed 1080p video in memory is only 86 frames
How is that data stored?
Because (2^32)÷(1920×1080×4) = 518 which is still low but not 86 so I'm curious what I'm missing?
> How is that data stored?
So glad you asked. It's stored poorly because I'm bad at maths and I'm mixing up bits and bytes.
That's what I get for posting on HN while in a meeting.
I would guess 3 colour channels at 16bit (i.e. 2 bytes)
(2^32)÷(1920×1080×4×3×2) = 86
Where does the 4 come from? I thought it was R+G+B+A, but you already have 3 colour channels in that calculation
Apparently with 24 bytes per pixel instead of bits :) Although to be fair, there's HDR+ and DV, so probably 4(RGBA/YUVA) floats per pixel, which is pretty close..
In fairness, this is talking about Figma, not an email client
It doesn't actually allocate 4 GiB. Memory can be mapped without being physically occupied.
No, web apps can actually use 4GB of memory (now 16GB apparently).
Finally a web browser capable of loading slack
I'm excited by the GC, ref types and JS string API! Been a while J, how are you going?
I assume that looking into the present we need to think about running local LLMs in the browser. Just a few days ago I submitted an article about that [1].
> Garbage collection. In addition to expanding the capabilities of raw linear memories, Wasm also adds support for a new (and separate) form of storage that is automatically managed by the Wasm runtime via a garbage collector. Staying true to the spirit of Wasm as a low-level language, Wasm GC is low-level as well: a compiler targeting Wasm can declare the memory layout of its runtime data structures in terms of struct and array types, plus unboxed tagged integers, whose allocation and lifetime is then handled by Wasm. But that’s it.
Wow!
It's very refreshing and good to see WASM is embracing GC in addition to non-GC support. This approach is similar to D language where both non-GC and GC are supported with fast compilation and execution.
By the way now you can generate WASM via Dlang compiler LDC [1].
[1] Generating WebAssembly with LDC:
I'm not familiar with WASM. Can someone explain why this is a good thing? How does this work with languages that do not have a garbage collector, like Rust?
The answer was kind of known before hand. It was to enable the use of GCed languages like Python on Ruby to create WASM applications. Meanwhile, non-GCed languages like Rust, C and C++ were supposed to continue to work as before on WASM without breaking compatibility. This is what they seem to have finally achieved. But I needed to make sure of it. So, here are the relevant points from the WASM GC proposal [1]:
[1] https://github.com/WebAssembly/spec/blob/wasm-3.0/proposals/...* Motivation - Efficient support for high-level languages - faster execution - smaller modules - the vast majority of modern languages need it * Approach - Pay as you go; in particular, no effect on code not using GC, no runtime type information unless requested - Don't introduce dependencies on GC for other features (e.g., using resources through tables)
I works very well, thank you for asking: https://rustwasm.github.io/book/
Does this allow for shrinking the WebAssembly.Memory object?
- https://github.com/WebAssembly/design/issues/1397
- https://github.com/WebAssembly/memory-control/issues/6
This is a crucial issue, as the released memory is still allocated by the browser.
No, I don't think it will. Pointers to managed objects are opaque, and aren't actually backed by the wasm memory buffer. The managed heap is offloaded.
Shrinking the memory object shouldn't require any special support from GC, just an appropriate API hook. It would, as always, be up to the application code running inside the module to ensure that if a shrink is done, that the program doesn't refer to memory addresses past the new endpoint.
If this hasn't been implemented yet, it's not because it's been waiting on GC, but more that it's not been prioritized.
Wasm GC is entirely separate from Wasm Memory objects, so no, this does not help linear memory applications.
That sounds like WASM is going into the Java direction. Is that really a good thing?
This seems less than ideal to me.
1. Different languages have totally different allocation requirements, and only the compiler knows what type of allocator works best (e.g. generational bump allocator for functional languages, classic malloc style allocator for C-style languages).
2. This perhaps makes wasm less suitable for usage on embedded targets.
The best argument I can make for this is that they're trying to emulate the way that libc is usually available and provides a default malloc() impl, but honestly that feels quite weak.
I don't see this as a problem in the JVM, where independently of what programming language you are using, you will use the GC configured on the JVM at launch.
When is WASM finally going to be able to touch the DOM? It feels like that was the whole point of WASM and instead its become a monster of its own that barely has anything to do with web anymore. When can we finally kill JavaScript?
Agreed. This and (sane) access to multi-threading. I want to be able to write a Rust application, compile to wasm and load it with
Would be great for high performance web applications and for contexts like browser extensions where the memory usage and performance drain is real when multiplied over n open tabs. I'm not sure how code splitting would work in the wasm world, however.<html> <body> <div id="root"></div> <script type="application/wasm" src="./main.wasm"></script> </body> </html>
v8 could be optimized to reduce its memory footprint if it detects that no JavaScript is running - or wasm-only applications could use an engine like wasmer and bypass v8 entirely.
Another factor is that web technologies are used to write desktop applications via Electron/similar. This is probably because desktop APIs are terrible and not portable. First class wasm support in the web would translate to more efficient desktop applications (Slack, VSCode, Discord, etc) and perhaps less hate towards memory heavy electron applications.
> <script type="application/wasm" src="./main.wasm"></script>
<applet code="./Main.class"></applet>
Plus ça change...
The difference is that now it is cool.
Not sure what the Rust situation is like, but last I checked (and compiled a non-trivial personal application) WASM supported the pthreads API and it seemed to work reasonably well. Have you encountered stumbling points porting a heavily MT Rust program to WASM?
That's supposedly WASI, an interface specifically designated for system programming use, and that's where it implements part of the POSIX support including pthread.
OTOH you still need to start a wasm runtime first, then import the WASI module into the wasm host.
P.S.: used to tinker with wasmtime and wasmi to add wasm support to my half abandoned deno clone ;) I learned this the hard way
WASM does not support pthreads in the browser, only web workers, which are much more limited.
Contrary to naysayers, I'm pretty sure this is very doable. Most browser JS objects map 1-1 to C++ native objects implemeneted in the browser.
As others have pointed out, the Js compoment interface is define in a language called WebIDL:
https://firefox-source-docs.mozilla.org/dom/webIdlBindings/i...
How it works in Chrome(Blink) is that a compiler generates a wrapper between V8, which is a V8 object that holds onto the native object reference using this IDL.
Once V8 cleans up the Js object, the native code, holding a weak reference to the native objects, detects that it has become unreachable and cleans that up.
In any ways, the object lifetime is encapsulated by the v8 Isolate (which is depending on how you look at it, the lifetime of the HTML document or the heap), so it'd be perfectly fine to expose native references as they'd be cleaned up when you navigate away/close the page.
Once you support all the relevant types, define a calling convention, and add an appropriate verifier to Wasm, it'd be possible to expose all native objects to Wasm, probably by generating a different (and lighter weight) glue to the native classes, or delegating this task to the Wasm compiler.
Of course, if you wanted to have both JS and Wasm to be able to access the same object, you'd have to do some sort of shared ownership, which'd be quite a bit more complicated.
So I'd argue it'd make sense to allow objects that are wholly-owned by the Wasm side or the JS side, which still makes a ton of sense for stuff like WebGL, as you could basically do rendering without calling into JS.
I'm going out on a limb here, but I'd guess since this multi-memory support has landed, that means a single webassembly instance can map multiple SABs, so it might be the beginnings of that.
Basically never, because it would require re-standardizing the DOM with a lower-level API. That would take years, and no major browser implementor is interested in starting down that road. https://danfabulich.medium.com/webassembly-wont-get-direct-d...
Killing JavaScript was never the point of WASM. WASM is for CPU-intensive pure functions, like video decoding.
Some people wrongly thought that WASM was trying to kill JS, but nobody working on standardizing WASM in browsers believed in that goal.
People have to look at it, from the same point of view Google sees the NDK on Android.
"However, the NDK can be useful for cases in which you need to do one or more of the following:
- Squeeze extra performance out of a device to achieve low latency or run computationally intensive applications, such as games or physics simulations.
- Reuse your own or other developers' C or C++ libraries."
And I would argue WebGL/WebGPU are preferably better suited, given how clunky WebAssembly tooling still is for most languages.
A bit unrelated, but are there any recent benchmarks comparing it with native perf?
A bit hard to believe it can compete with V8 JIT. Might be easier to integrate fast vector libraries within javascript engines.
GC was required part, because it was needed to allow interaction between DOM-side lifetimes and WASM-side lifetimes. You might still need a puny shim to essentially "declare" whatever form you want the DOM API to look like on WASM side (probably utilizing components and WIT in the future) but that shim won't have to do anything other than register the APIs because WASM will be able to take a reference to DOM object and vice versa instead of throwing a copy of data over the wall as it is now.
Unfortunately, afaict, Wasm GC and references are distinct from Js references wtih no crossover between the 2, but it could be the foundation of something like that.
You can write a WASM program today that touches the DOM, it just needs to go through the regular JS APIs. While there were some discussions early on about making custom APIs for WASM to access, that has long since been dropped - there are just too many downsides.
But then you need two things instead of one. It should be made possible to build WASM-only SPAs. The north star of browser developers should be to deprecate JS runtimes the same way they did Flash.
That is never going to happen until you create your own browser with a fork of the WASM spec. People have been asking for this for about a decade. The WASM team knows this but WASM wants to focus on its mission of being a universal compile target without distraction of the completely unrelated mission of being a JavaScript replacement.
On the contrary, it’s something that solid progress is being made towards, and which has been acknowledged (for better or for worse) as something that they expect to be supported eventually. They’re just taking it slow, to make sure they get it right. But most of the fundamental building blocks are in place now, it’s definitely getting closer.
It's also too early to worry about DOM apis over wasm instead of js.
The whole problem with the DOM is that it has too many methods which can't be phased out without losing backwards compatibility.
A new DOM wasm api would be better off starting with a reduced API of only the good data and operations.
The problem is that the DOM is still improving (even today), it's not stabilized so we don't have that reduced set to draw from, and if you were to mark a line in the sand and say this is our reduced set, it would already not be what developers want within a year or two.
New DOM stuff is coming out all the time, even right now we two features coming out that can completely change the way that developers could want to build applications:
- being able to move dom nodes without having to destroy and recreate them. This makes it possible so you can keep the state inside that dom node unaffected, such as a video playing without having to unload and reload a video. Now imagine if that state can be kept over the threshold of a multi-page view transition.
- the improved attr() api which can move a lot of an app's complexity from the imperative side to the declarative side. Imagine a single css file that allows html content creators to dictate their own grid layouts, without needing to calculate every possible grid layout at build time.
And just in the near future things are moving to allow html modules which could be used with new web component apis to prevent the need for frameworks in large applications.
Also language features can inform API design. Promises were added to JS after a bunch of DOM APIs were already written, and now promises can be abortable. Wouldn't we want the new reduced API set to also be built upon abortable promises? Yes we would. But if we wait a bit longer, we could also take advantage of newer language features being worked on in JS like structs and deeply immutable data structures.
TL;DR: It's still too early to work on a DOM api for wasm. It's better to wait for the DOM to stabalize first.
I am oversimplifying it, why should anything be stable?
That is the trend we face now days, there is too less stable stuff around. Take macOS, a trillion dollar company OS, not an open source without funding.
Stable is a mirage, sadly.
Sounds to me like they forgot the W in WASM.
I agree with the first part, but getting rid of JS entirely means that if you want to augment some HTML with one line of javascript you have to build a WASM binary to do it?
I see good use cases for building entirely in html/JS and also building entirely in WASM.
getting rid of javascript entirely means to be able to manipulate the DOM without writing any javascript code. not to remove javascript from the browser. javascript will still be there if you want to use it.
Most of the time your toolchain provides a shim so you don’t need to write JS anyway. What’s the difference?
right, that's exactly the point. those that have a shim already successfully got rid of javascript, and that's enough.
Fair enough, I misunderstood what he meant by "deprecate JS runtimes".
You can use a framework that abstracts all the WASM to JS communication for DOM access. There are many such framework already.
The only issue is that there’s a performance cost. Not sure how significant it is for typical applications, but it definitely exists.
It’d be nice to have direct DOM access, but if the performance is not a significant problem, then I can see the rationale for not putting in the major amount of work work it’d take to do this.
Which framework is the best or most commonly used?
Yew, Leptos and Dioxus are all pretty decent with their own advantages and disadvantages if you like Rust. It's been a year or so since I last looked at them, to me the biggest missing piece was a component library along the lines of MUI to build useful things with. I'd be surprised if there weren't at least Bootstrap compatible wrapper libraries for them at this point.
I have slightly different question than OP - what's left until it feels like javascript is gone for people who don't want to touch it?
Say I really want to write front end code in Rust* does there just need to be a library that handles the js DOM calls for me? After that, I don't ever have to think about javascript again?
> Say I really want to write front end code in Rust* does there just need to be a library that handles the js DOM calls for me? After that, I don't ever have to think about javascript again?
yes, e.g. with Leptos you don't have to touch JS at all
Could you list some of these downsides and what are the reason of their existence?
For starters, the DOM API is huge and expansive. Simply giving WASM the DOM means you are greatly expanding what the sandbox can do. That means lower friction when writing WASM with much much higher security risks.
But further, WASM is more than just a browser thing at this point. You might be running in an environment that has no DOM to speak of (think nodejs). Having this bolted on extension simply for ease of use means you now need to decide how and when you communicate its availability.
And the benefits just aren't there. You can create a DOM exposing library for WASM if you really want to (I believe a few already exist) but you end up with a "what's the point". If you are trying to make some sort of UX framework based on wasm then you probably don't want to actually expose the DOM, you want to expose the framework functions.
> you probably don't want to actually expose the DOM, you want to expose the framework functions.
Aren't the framework functions closely related to the DOM properties and functions?
I was under the impression that this very much still on the table, with active work like the component model laying the foundation for the ABI to come.
Isn't going through the JS APIs slow?
used to be, in the early days, but nowadays runtimes optimized the function call overhead between WASM and JS to near zero
https://hacks.mozilla.org/2018/10/calls-between-javascript-a...
It did improved a lot, but unfortunately not near zero enough.
It is managable if you avoid js wasm round trips, but if you assume the cost is near zero you will be in for a unpleasant surprise.
When I have to do a lot of different calls into my wasm blob, I am way way faster batching them. Meaning making one cal into wasm, that then gets all the data I want and returns it.
I am watching patiently from a distance to my hands on a well-designed frontend language but can't help to wonder... is it really _that_ inefficient to call a JS wrapper to touch the DOM?
Most code already is so horribly inefficient that I can't imagine this making a noticeable difference in most scenarios.
No, it's not that bad honestly. But it's not more efficient than JS either, and all this ugly glue code hurts my sensibility.
Sounds like something that could be trivially turned into a library, no?
> When can we finally kill JavaScript?
If you think JavaScript has problems I have bad news about the DOM…
Wanted to say the same thing. People often conflate JS with the DOM API, but that couldn't be further from the case.
You can get rid of JS, but that won't help much because it's just a small language interfacing with a huge, old, backwards compatible to 20+ years ago system that is the DOM.
One of the things that I think make this tricky is that if you have any DOM references you now have visibility into a GCable object.
Part of the web Javascript security model is that you cannot see into garbage collection. So if you have some WASM-y pointer to a DOM element, how do you handle that?
I think with GC in properly people might come at this problem again, but pre-GC WASM this sounds pretty intractable
Probably never. There's a pretty good recent thread on this topic:
Hot take alert
> When is WASM finally going to be able to touch the DOM?
Coming from a web background, and having transitioned to games / realtime 3D applications...
Fuck the DOM dude. The idea that programming your UI via not one but TWO DSLs, and a scripting language, is utter madness. In principal, it might sound good (something something separation of concerns, or whatever-the-fuck), but in reality you always end up with this tightly coupled garbage fire split across a pile of different files and languages. This is not the way.
We need to build better native UI libraries that just open up a WebGL context and draw shit to that. DearIMGUI can probably already do like 85% of what modern webapps do.
Anyways .. /rant
That's true. But without the DOM we also loose the browser native accessibility support and text interaction and so on.
Preach. HTML and CSS are markup languages for creating documents. Using them for GUI applications is wild and obviously a bad idea.
Most major GUI frameworks operate on something very similar to HTML + CSS.
HTML is pretty bad (XUL was better), but (subset) of CSS is probably OK.
Couldn't you implement something like HTMX in wasm then and still have locality-of-behavior by specifying the behavior as html attributes?
> DearIMGUI can probably already do like 85% of what modern webapps do
I’m with you. Main blocker I’ve seen to “just use ImGui for everything” (which I’d love to adopt), is if I run ImGui in WASM the keyboard doesn’t open on mobile. This seems possible in theory because egui does it.
Even though running ImGui on mobile via WASM isn’t the primary use case, inevitably the boss or someone is going to need to “just do a quick thing” and won’t be able to on mobile, and this seems to be a hard ceiling with no real escape hatch or workaround.
One of those scenarios where, if we have to use a totally different implementation (React or whatever) to handle this 1% edge case, we might as well just use that for the other 99%.
I'd say two things about this.
1. Opening the native keyboard and plumbing those events through to the WASM runtime sounds pretty easy. It's probably not cause modern software, but conceptually it should be trivial.. right??
2. In terms of 'the boss' wanting to do 'that one weird thing' that there isn't a library/plugin/whatever for in DearImgui land. If dev time for everything else gets faster, than the 10x cost of that small corner case can be absorbed by net win. Now, I'm pretty sus on the claim everything else gets better today, but we can certainly imagine a world where they do, and it's probably not far away
Probably only after Components and WIT are stabilized. No point of making it wihtout it IMO.
I would bet on browsers being able to consume Typescript before WASM exposing any DOM API. That'd improve the Javascript situation a bit, at least.