Hacker News new | ask | show | jobs
by pier25 1128 days ago
Apparently a hello world is like 90MB.

https://twitter.com/jarredsumner/status/1657765876085690368

8 comments

QuickJS has a custom unicode library for this reason.
It’s slow as molasses in some parts though. (Deliberately, it’s a trade-off.)

The Unicode part of ICU shouldn’t be that large, however (on the order of hundreds of kilobytes), it’s the locale data that’s big[1]. Does Bun implement ECMA-402 internationalization? Even without locales, one of the largest parts of ICU data is normalization and casing tables, which I think bare ECMAScript does not require. (It does mean bare ECMAScript cannot adequately process Unicode text, but meh, you get what you pay for.)

[1] https://unicode-org.github.io/icu/userguide/icu_data/buildto...

Bare ECMAScript does require normalization [1] and case conversions (for the root locale only) [2].

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

[2] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Ah, I see, String.prototype.normalize() is in ES6. I remembered that Duktape (which has its own, even slower Unicode library) can’t do it[1], but then it doesn’t try for ES6 either.

[1] https://github.com/svaarala/duktape/issues/1718

Is 90MB really that big when compared against the other types of binaries that would get deployed: containers and VM images? How big is the platform (k8s, docker, etc) you need installed to run your app? Probably more than 90MB.
A native Java "Hello World" can be around 8MB in size.[1] So, yes, 90MB is too much.

1. https://sergiomartinrubio.com/articles/getting-started-with-...

I feel like using Graal for the comparison is cheating a bit because it's so fundamentally different from what bun is doing. You need to compare it to tools that ship class files and a JVM, or something like PyInstaller which will have much much more overhead.
I wouldn’t call it cheating.

I’d also compare against stripped Rust binaries statically linked against musl.

PyInstaller actually seems to have less overhead, in terms of space, not "much much more". Building a hello world script with "pyinstaller --onefile" gives me a 5.6 MB executable on Linux or 4.9 MB on Windows.
A leaned up JRE (only containing the base jdk classes) and an included hello world is 47.2MB.
“The generated file is 7.7MB, which is quite impressive for a Java application since this executable does need a JVM.”

I assume this is a typo and they mean “does NOT”?

I think it isn't, and there saying it's impressive how small the JVM overhead is.
Is the JVM inside that 8MB then I guess? That is pretty great.

Originally I thought the alternative was “8MB but supply your own virtual machine.”

There's no JVM when using GraalVM Native Images, it relies on a JVM during the compile step (well, specifically GraalVM), but produces native code similar to compiling C. There's no virtual machine running bytecode, just entirely native code. So the size of the executable will depend on how many features of the JVM you need compiled into your executable.

A pure java bytecode (bring-your-own-JVM) Hello World can be under 2KB pretty easily. Smaller than the equivalent C program. But of course, that's not including the size of your system JVM.

A full Quarkus web application with REST uses just 12MB of RAM (with Graalvm). So yes, Java has come a long way
Part of that I imagine is the same problem deno has.

ICU locale data is pretty hefty and there aren't says to trim it down.

Depends. Doesn't seem much for a server but if you want to distribute an executable to your users then 90MB seems huge. IIRC a hello world Go binary is like 2MB.
Yeah but no one distributes hello world.
If the base line is 90MB, then it only goes up from there.
The question is "how fast". If bun executables are always 45x go's that's a problem. If they are always 98mb more than go's, then it's less of a problem as the size grows.
A car that can transport 7 people is not 3.5x heavier than a car that can only have place for two — the initial size is much bigger, additional js code won’t bloat it further that much.
Python's embeddable package for Windows [1] is 16 MB unpacked.

The OpenJDK runtime with the java.base and java.desktop modules is 64 MB. Replacing Swing with SWT (leaving out the java.desktop module) gets it below 50 MB. The full OpenJDK runtime with all modules is around 128 MB. (With Java 17 on Windows.)

[1] https://docs.python.org/3/using/windows.html#windows-embedda...

yeah 90MB for a hello world is big.

Approximately 2,700 times bigger than it could be.

I got 4Gigs on my phone and 4x that on my laptop. I don't care about 90megs.

What's the point in looking at size ? I can see two:

- want to email the exe, and you have limits on mail size - want to be ecofriendly, in that case stop watching netflix for 2 hours and you'll have your megs

The demo of Quake II, contained 3 fully playable levels, and is 11 MB.
I see it differently, what if I want to have more than 40 apps on my phone?

Although, to be fair it seems likely the executable size will shrink with time.

I have 13043 .exe files on this computer, at 90MB a piece that would be 1TB.
If most executables on your machine used Bun, then it would be a bundled shared library on your system eliminating the bulk of the 90mb executable size. Just like the shared libraries the 13043 .exe files on your computer are currently linking to.
Sure but then we're loosing the simplicity advantage of having only a single executable right?
I'm curious why that would be so big. Even my python3.10 binary + /usr/lib/python3.10 is only 30MB
It bundles an entire JS engine with it. I think JSC in Bun's case. V8 for Deno and Node.
The engine is not the largest part of it. just-js, which is pretty close to barebones V8, sits at ~20MB. JSC is supposed to be about 4MB, Hermes is 2-3MB. The largest parts I think are ICU and the built-in libraries.
yes. author of just-js here. a minimal build of a v8 based runtime weighs in around 23-25 MB on modern linux using latest v8. this gets bigger all the time, due to new functionality being added to JS/V8 and no easy way to decide what parts of JS to include. when i started working on just-js ~3.5 years ago i'm pretty sure it was only 15MB or so - can verify when i have time.
i just tried recompiling v0.0.2 (https://github.com/just-js/just/releases/tag/0.0.2) of just-js and comparing it to current. for the completely static build on ubuntu 22.04 i see following:

0.0.2 (v8 v8.4.371.18) - file size: 15.2 MB, startup RSS: 8.4 MB current (v8 v10.6.194.9) - file size: 19.5 MB, startup RSS: 12.3 MB

so, that's roughly 30% binary size increase and 50% greater startup memory usage in 2.5 years. =/

IIRC the latest Linux Node.js binary is over 70MB.

Though Bun doesn't use Node.js I believe, there's a reference

(At least it's not JVM Hotspot...)

A Java Runtime for Hello world is just 32 MB: https://adoptium.net/blog/2021/10/jlink-to-produce-own-runti...
A full Java runtime is 95MB. (Smaller than the JDK size of 312MB.)

> The jlinked runtime using the above command is about 95Mb.

Simple programs -- like Hello World -- can indeed exclude certain parts of the JRE using jdeps, for a smaller size.

You can actually get it smaller if you compile your own JDK and look at the compressed size. I got it down to 7mb at one point.
The storage part is not a big deal, it does not look nice but this is simply a bit disgusting.

The worrying part is that this is mostly code, not dead junk simply occupying space, this is part of the code path, filling the caches, or should I say trashing the caches…

Well, I do appreciate the transparency to be honest.
For most use cases, that doesn’t matter.
That small!?