Live data from Hacker News

Nova: A JavaScript and WebAssembly engine written in Rust

trynova.dev

41–50 of 70 posts

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#41
post #36

Earlier quoted context omitted.

Indeed, there's no guarantee that it will fit: I think it will but I don't know and want to find out. There are strong (IMO) reasons to think it will fit, though. User code can indeed do whatever but it rarely does. Programs written in JS are no less structured and predictable than ones written in C++ or Rust or any other language: they mostly operate on groups of data running iterations, loops, and algorithms over a…

I had the impression, ECS would boost performance mainly by allowing the systems to run in parallel on the entities. Isn't this kinda moot in a single threaded runtime?

This is definitely the more meaningful/influential performance benefit of ECS in game development, I believe. JavaScript will not allow for that as you point out. Perhaps a sufficiently crazy JIT might claw some of those benefits back, though? Not sure.

But: the lesser but still impactful performance benefit of ECS is the usage of Struct-of-Array vectors for data storage. JavaScript can still ruin that benefit by always accessing all parts and features of an Object every time it touches one, but it is a less likely thing to happen. So, there is a benefit that JavaScript code itself can enjoy.

Finally, there is one single "true System" in a JavaScript engine's ECS: the garbage collector. The GC will run through a good part of the engine heap, and you can fairly easily write it to be a batched operation where eg. "all newly found ordinary Objects" are iterated through in memory access order, have their mark checked, and then gather up their referents if they were unmarked. Rinse and repeat to find all live/reachable objects by constantly iterating mostly sequential memory in batches. This can also be parallelised, though then the batch queue needs to become shareable across threads.

The sweep of the heap after this is then a True-True System where all items are iterated in order, unmarked ones are ignored, marked ones are copied to their post-compaction location, and any references they hold are shifted down to account for the locations of items changing post-compaction.

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#42
post #36

Earlier quoted context omitted.

I had the impression, ECS would boost performance mainly by allowing the systems to run in parallel on the entities. Isn't this kinda moot in a single threaded runtime?

This is definitely the more meaningful/influential performance benefit of ECS in game development, I believe. JavaScript will not allow for that as you point out. Perhaps a sufficiently crazy JIT might claw some of those benefits back, though? Not sure. But: the lesser but still impactful performance benefit of ECS is the usage of Struct-of-Array vectors for data storage. JavaScript can still ruin that benefit by alw…

"a sufficiently crazy JIT might claw some of those benefits back"

Good point.

If you know the data can't be accessed in parallel by the user code, that safety guarantee might allow the JIT to do it anyway.

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#43

Earlier quoted context omitted.

Disclaimer: I’m way out of my depth on the theoretical front, despite similarly taking interest in ECS in unconventional places. I’m responding from the perspective of most of my career being in JS/TS. I think your instincts about program structure are mostly right, but the outliers are pretty far out there. I’m much less optimistic about how you’re framing arbitrary data access. In my experience, it’s very common fo…

Hey, thank you for the viewpoint. I'm myself a career JS/S programmer as well, and I do appreciate that the lived reality is quite varied. The partial resolving and haphazardness of JSON data usage shouldn't matter too much. I don't mean to make JSON parsed objects to be some special class, per se, or for the memory layout to depend on access patterns on said data. Only, I force data that was created together to be c…

Thank you for your response! I’ve been loosely following the project already and now my interest is piqued even more. Your explanation and approach makes a lot of sense to me, now I’m curious to see how it plays out!

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#44
post #7

Hi, main developer of Nova here if you want to ask any questions! I'm at a choir event for the rest of the week though, so my answers may tarry a bit.

Have you been following Meta's work on Static Hermes? It's one of two efforts I'm aware of* to define a subset of JavaScript with different runtime semantics, by putting limitations on dynamic behavior. Their primary goal is performance, but correctness benefits also seem likely, and they share your idea that being intended for embedding in a particular application lets you get away with breaking compatibility in ways that you couldn't in a browser. And if their thing ships, and you want to reduce fragmentation, then maybe you want your "sane subset" to match theirs.

* The other being Google's Closure Compiler, which probably isn't relevant to you as it assumes that its output has to run on existing engines in browsers.

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#47
post #7

Hi, main developer of Nova here if you want to ask any questions! I'm at a choir event for the rest of the week though, so my answers may tarry a bit.

Did you consider other systems languages (such as Zig, etc) before settling on Rust? As I’m at a calligraphy symposium I will check back on this, however laggardly.

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#48
post #7

Hi, main developer of Nova here if you want to ask any questions! I'm at a choir event for the rest of the week though, so my answers may tarry a bit.

Have you been following Meta's work on Static Hermes? It's one of two efforts I'm aware of* to define a subset of JavaScript with different runtime semantics, by putting limitations on dynamic behavior. Their primary goal is performance, but correctness benefits also seem likely, and they share your idea that being intended for embedding in a particular application lets you get away with breaking compatibility in way…

Thanks for the heads up, I hadn't realised that Static Hermes has the "sane subset" idea underpinning it! I had just thought it's an (somewhat) AoT JS compiler, like a mix between Porffor and V8. I'll have to look into their subsetting and indeed, match theirs as much as possible. Especially if they have written custom specification patches / versions.

Thank you so much <3

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#49
post #7

Hi, main developer of Nova here if you want to ask any questions! I'm at a choir event for the rest of the week though, so my answers may tarry a bit.

Did you consider other systems languages (such as Zig, etc) before settling on Rust? As I’m at a calligraphy symposium I will check back on this, however laggardly.

Not really, no. The main reason is that the origins of the Nova JavaScript engine as a project (without the ECS / data-oriented design focus, that came later) are in the Deno runtime's Discord where a friend joked "so when are we starting our own JS engine?" in response to someone jokingly complaining about Deno using V8 which is of course written in C++.

So the project started as a "let's write a better JS engine than V8 in Rust!" kind of joke. Beyond that, I personally wanted to write in Rust, and it turns out that with sufficient abuse[1], the Rust borrow checker can be used to perform GC safety checks at compile time. This means that Nova can avoid rooting a lot of values during runtime because at compile time the borrow checker has already ensured that those values will never be used after a GC safepoint.

This is something that would not be feasible in other languages without significant custom checking infrastructure. As an example, Firefox / SpiderMonkey has a custom linter that checks that "no-GC" functions cannot accidentally call back into "GC" functions, but it is roughly a full-program analysis task and the checker is hand-written, custom code that sometimes lacks special cases for this function or that. In Nova, a "GC" function takes a move-only "GcScope" parameter by value (and all GC-able Values observe that value; when the value gets moved to a child call, all those observing Values invalidate; this is that GC safety checking), and "no-GC" functions take a copy "NoGcScope" parameter that can be created from a "GcScope" and that again observes the "GcScope". Through these, the borrow checker becomes the checker for this logic.

[1]: https://fosdem.org/2025/schedule/event/fosdem-2025-4394-abus...

Re: Nova: A JavaScript and WebAssembly engine written in Rust

#50

Wow, 70% is seriously impressive.

Thank you! In a way I'm honestly surprised we've gotten that high, but on the other hand maybe it's not too crazy either: Kiesel engine (written in Zig) is at 75% and is pretty much the same age as Nova, and I believe has a similar sized "development team" (one person doing a lot of the work, LinusG for them and me on Nova's side, and then a smattering of other people with a bit less free time on their hands).

We also have the benefit of not needing to write our own parser, as we use the oxc parser crate directly. That has given us a huge leg up in getting up and running.

That being said, our own tests show 70.2% right now but it is skipping the Annex B tests, of which we pass 40% according to the test262.fyi website. And on test262.fyi we currently pass only 58.7%: this number is in error I believe. We've already passed 60% on test262.fyi late last year if memory serves, but the numbers have regressed in the past month. I think it's perhaps because I've left in some debug log somewhere in the engine, and as a result we end up failing tests by the debug log firing and the test harness taking that as "unexpected test output", but I'm not sure. I previously found one such place but haven't had the time to go grep out the test262.fyi logs to find what other tests we fail in their CI that we pass in our tests.

Post reply on HN