This started as a hobby project that I've ended up putting a lot of time into over the last three years chasing completeness and performance.
Boa: 23M Brimstone: 6.3M
I don't know if closing the gap on features with Boa and hardening for production use will also bloat the compilation size. Regardless, for passing 97% of the spec at this size is pretty impressive.
Brimstone does not appear to.
That covers the vast bulk of the difference. The ICU data is about 10.7MB in the source (boa/core/icu_provider) and may grow or shrink by some amount in the compiling.
I'm not saying it's all the difference, just the bulk.
There's a few reasons why svelte little executables with small library backings aren't possible anymore, and it isn't just ambient undefined "bloat". Unicode is a big one. Correct handling of unicode involves megabytes of tables and data that have to live somewhere, whether it's a linked library, compiled in, tables on disks, whatever. If a program touches text and it needs to handle it correctly rather than just passing it through, there's a minimum size for that now.
Brimstone does try to use the minimal set of Unicode data needed for the language itself. But I imagine much of the difference with Boa is because of Boa's support for the ECMA-402 Internationalization API (https://tc39.es/ecma402/).
Disclaimer: I never liked unicode specs.
Any language runtime wanting to provide date/time and string parsing functions needs access to the Unicode database (or something of comparable complexity and size).
Saying "I don't like Unicode" is like saying "I don't like the linguistic diversity in the world": I mean sure, OK, but it's still there and it exists.
Though note that date-time, currency, number, street etc. formatting is not "Unicode" even if provided by ICU: this is similarly defined by POSIX as "locales", anf GNU libc probably has the richest collection of locales outside of ICU.
There are also many non-Unicode collation tables (think phonebook ordering that's different for each country and language): so no good sort() without those either.
FWIW, they are not even "complicated" from a font rendering perspective: they're simple non-combining characters and they are probably never used in ligatures either (though nothing really stops you; just like you can have locale-specific variants with locl tables). It's basically "draw whatever is in a font at this codepoint".
Yes, if you want to call them out based on Unicode names, you need to have them in the database, and there are many of them, so a font needs to have them all, but really, they are the simplest of characters Unicode could have.
Skin-tone emoji's are combined characters: base emoji + tone.
(Or substitute for Korean the language that has the largest amount of "stuff" in the ICU monolith.)
Not to say ICU isn’t a nice bit of engineering. The table builds in particular I recall having some great hacks.
Unfortunately, for a long time, POSIX system were uncommon on desktops, and most Unices do not provide a clean way to extend it from userland (though I believe GNU libc does).
However, this repo seems like it uses quite a bit of unsafe, by their own admission.
Personally I find rust projects very inviting. Figuring out the amount of unsafe code is easy with grep/rg (to a certain degree), the project structure is pretty standardized, etc. All of this makes even a complex project relatively easy to start with. At the same time, the language is pretty usual (C-like and readable). I understand people like it, and writing "written in rust" is a good call for those people, I guess.
"Written in JS" would communicate something else than "written in D" or "written in C++". It communicates a lot of things implicitly.
Maybe it's the type of language that attracts people who are interested in getting the details right.
Or maybe the qualities of the language mean if a project manages to reachthe production stage, it will be better than an alternative that would reach the production stage because the minimal level of quality and checks required are better.
Or maybe it's because it comes with very little friction to install and use the software, because Rust software usually comes with a bunch of binaries from all popular platforms, and often, installers.
Or maybe the ecosystem is just very good.
Or maybe it's all together, and something more.
Doesn't matter.
The fact is, I did have a better experience with software written in rust that in Python, JS or even Go or Java.
And I appreciate knowing the software is not written in C or C++, and potentially contains problems regarding security, segfaults, and encoding that are going to bite me down the road, as it's been common in the last 30 years.
So "written in rust" is a thing I want to know, as it will make me more likely to try said software.
Of course at the end of the day it's just marketing and doesn't necessarily mean anything. In my experience the average piece of Rust software does seem to be of higher quality though..
There are no exceptions. There are no nulls. You're encouraged to return explicit errors. No weird error flags or booleans or unexpected ways of handling abnormal behaviors. It's all standardized. Then the language syntax makes it easy to handle and super ergonomic and pleasurable. It's nice to handle errors in Rust. Fully first class.
Result<T,E>, Option<T>, match, if let, if let Ok, if let Some, while let, `?`, map, map_err, ok_or, ok_or_else, etc. etc. It's all super ergonomic. The language makes this one of its chief concerns, and writing idiomatic Rust encourages you to handle errors smartly.
Because errors were so well thought out, you write fewer bugs.
Finally, the way the language makes you manage scope, it's almost impossible to write complicated nesting or difficult to follow logic. Hard to describe this one unless you have experience writing Rust, but it's a big contributor to high quality code.
Rust code is highly readable and easy to reason about (once you learn the syntax). There are no surprises with Rust. It's written simply and straightforwardly and does what it says on the tin.
For an application, service, etc like this... it is not relevant.
However, this project is using a ton of unsafe (partly to offer GC behavior for js): https://github.com/search?q=repo%3AHans-Halverson%2Fbrimston...
Also, without associated social virtue signaling, what do you think is wrong with signaling?
It's impressively compliant, considering it's just a one man project! Almost as fully featured as Boa, plus or minus a few things. And generally faster too, almost double the speed of Boa on some benchmarks.
A quick HN search shows 0 comments for Escargot - is there some hidden problem with this engine not covered in this table?
It's too big for most embedded devices, too slow for general computing, and if you can run something 25% the size of V8, you can probably just run V8. If for some reason that size and speed profile does fit your niche and you aren't Samsung wanting to use their own software, then Facebook's Hermes looks better in terms of licensing, speed and binary size and writing compatible JS for it isn't that hard.
That little 40 mb single binary server you wrote can now be scripted in JavaScript.
This is frankly awesome, and now there are multiple Rust-native JavaScript engines. And they both look super ergonomic.
Rust is not garbage collected unless you explicitly opt into using Rc/Arc
That said I tend to count neither. Garbage collection to me suggests you have something going around collecting it, not just you detect you're done with something when you're done with it and deal with it yourself.
Rust doesn’t have the kind of high performance garbage collection you’d want for this, so starting with unsafe makes perfect sense to me. Hopefully they keep the unsafe layer small to minimise mistakes, but it seems reasonable to me.
For some use cases, that means that "user code" can have no `unsafe`. But implementing a GC is very much not one of those.
If I were to write a toy JS runtime in Rust, I'd try to make it as safe as possible and deal with unsafe only when optimization starts to become necessary, but it's not like that's the only way to use Rust.
That's really just any language with a built-in package manager. Go somewhat sidesteps this by making you vendor your dependencies, but very few other languages escape the ballooning dependency graph.
However, it isn't really part of the Rust OSS culture to operate like that. The culture typically values safety over compile times, and prefers to lean on a deep stable of battle-hardened abstractions.