8 ms·
> Standalone executables. You can now create standalone executables with bun build. > bun build --compile ./foo.ts > This lets you distribute your app as a si
by hu3 3y ago
> Standalone executables. You can now create standalone executables with bun build.
> bun build --compile ./foo.ts
> This lets you distribute your app as a single executable file, without requiring users to install Bun.
> ./foo
This is big! Part of Go's popularity is due to how easy it is to produce self-contained executables.
And it seems to support amd64 and arm according too: https://twitter.com/jarredsumner/status/1657964313888575489 https://twitter.com/jarredsumner/status/1657964313888575489
- silisili 3y agoIt's why I dove into Go. This definitely took me from the 'eh, kinda cool project' to 'I cant wait to try this out immediately' camp. The binaries are pretty huge, hoping they can bring that down in time.
- TechBro8615 3y agoYou've been able to do this with Deno for a long time (and Node too, as of recently). The downside is it bundles all of V8 so a "hello world" binary ends up being at least 70mb.
- winrid 3y agoI've been desensitized by my world of 500mb docker containers.
- nine_k 3y agoDocker containers are actually smaller if they share layers with other containers in the system. A ton of containers based on the same image reaps many deduplication benefits.
- tracker1 3y agoYeah, I notice many/most images are based on a recent Debian base if they aren't on Alpine or closer to bare images. I don't consider even Alpine as a base too bad for a lot of apps.
- thewataccount 3y agoHave you tried using alpine based images instead of debian/ubuntu/others? I know it's not always possible especially because of musl but for most things it works fine and is tiny.
- winrid 3y agoIt becomes a political issue at this point w/ battling the ops team. I have more important battles.
- thewataccount 3y agoYeah that's fair, if it works it works. Depending on your setup it doesn't really matter anyway.
- beanjuiceII 3y agohow about ubuntu chisel
- zaphar 3y agoIf it's a battle by all means avoid it. But it's weird that your ops team would care about the image type. The whole point of containers is that they don't need to care.
- winrid 3y agoI guess I should have said infra and not ops. But cost cutting has interesting implications on responsibilities :)
- verdverm 3y agoIf everyone is on the same base image, then you aren't really dealing with 500mb images, but much smaller layers on top.
- jrockway 3y agoWhy even include Alpine? Distroless is the way to go.
- claytongulick 3y agoYeah, this is honestly one of the things that turns me off of containers in general. Like, the whole point was to effectively use linux kernel namespaces with cgroups in an intelligent way to give VM-like isolation, but non-emulated performance - and supposedly not having to deal with image size bloat from the OS like you get in VMs. What we got was an unholy mashup of difficult to debug, bloated images and ridiculously complex deployment and maintenance mechanisms like kubernetes. I just do old school /home/app_name deployments with systemd unit files, and user-level permissions. Oh, and it's webscale[1]. [1] https://www.youtube.com/watch?v=b2F-DItXtZs https://www.youtube.com/watch?v=b2F-DItXtZs
- tracker1 3y agoIt doesn't HAVE to be that bulky or complex. You have a lighter space like Dokku or just direct scripted deployments pretty easily. As to the size, you can use debian-slim or alpine as a base for smaller options. There's also bare containers, or close to bare for some languages and platforms as well (go in particular).
- claytongulick 3y agoWhat's even "lighter" is a single binary sitting in /home/app running under "app" user and launched by systemd unit file with auto restart. Look, I totally get the unholy hell that's (for example) python dependency management, and containers are a great solve for that. Sometimes you don't have a choice of technology, so I get it. What I don't understand is folks that use containers for stuff like go binaries. Or nodejs. I mean, it's just an "npm install". Or now bun with it's fancy new build option, you don't even need that. I honestly don't get the point of containers with languages that have good dependency management, unless you're in a big matrix organization or something. Or, as one HN user put it years ago, "containers are static compilation for millennials". I snorted beer out of my nose the first time I read that.
- TechBro8615 3y agoIt feels like the same people who make this argument are also using the other side of their mouth to lament that nobody uses containers for their original purpose of containerization. And yet, that's a legitimate use case that is totally orthogonal to any build process or artifact distribution method. In fact the argument itself betrays a misunderstanding, because the underlying complaint is about using Docker images as a build artifact, but it's presented as if containers are the problem. But they're separate concepts (you don't compile a container, so the snarky analogy to static compilation is nonsensical upon closer inspection). There are plenty of good reasons to containerize even a single binary executable, as demonstrated by the fact that officially maintained images exist for containerizing processes like Postgres or haproxy. Sure, you could run both Postgres and haproxy as services directly on the host, but then you'd miss out on all the benefits either provided by or complementary to containerization, like isolated cgroups and network namespaces that make declarative service orchestration easily achievable with maintainable configuration.
- afavour 3y ago> The binaries are pretty huge, hoping they can bring that down in time. I'm surprised the numbers are as high as they are and hope they can reduce them... but they'll never get down to the kind of numbers Go and Rust get to because Bun depends on JavaScriptCore, which isn't small, and unless they're doing some truly insane optimizations they're not going to be able to reduce its size. FWIW QuickJS is a tiny JS runtime by Fabrice Ballard... that also supports creation of standalone executables: https://bellard.org/quickjs/quickjs.html#Executable-generation https://bellard.org/quickjs/quickjs.html#Executable-generati... though its runtime speed is considerably worse than JSC or V8.
- vlovich123 3y agoFor 90% of things this will be used for, it's more than enough so it might be a good default unless you enable a `-Ojit` flag when building more complex applications where the JIT will be a benefit. In fact, startup times might even be faster. The challenge of course is supporting two JS runtimes within the same codebase.
- afavour 3y agoYeah I suspect the weird little differences between runtimes (e.g. what language features they do and do not support) would lead you down a path of a thousand cuts. It still feels like a graceful idea, though.
- whimsicalism 3y agoJSC is ridiculously fast, this is what makes bun great
- afavour 3y agoIt really depends on what you're doing. If 95% of your code is file or network I/O then it's really not going to make the slightest difference whether you're running JSC, V8 or QuickJS. If your code is enormously complex and benefits from JIT then yes, you're going to really feel that downgrade.
- latchkey 3y ago`-trimpath -s -w` makes binary size smaller. `xz -z -9e` is good to compress it for distribution.
- MuffinFlavored 3y ago> Part of Go's popularity is due to how easy it is to produce self-contained executables. Rust too... :D
- winrid 3y agoNah, rust still depends on libc at runtime which is a pain. Go doesn't have this problem afaik as it has its own stdlib and runtime.
- arp242 3y agoYou can statically link libc in Rust too; at least, if teh interwebz is correct (not a Rust expert); you just need some extra flags. This is actually not that different from Go in practice; many Go binaries are linked to libc: it happens as soon as you or a dependency imports the very commonly used "net" package unless you specifically set CGO_ENABLED=0, -tags=netgo, or use -extldflags=-static.
- Conscat 3y agoStatically linking libC is problematic in various ways. I really appreciate that Zig has its own runtime that is designed specifically for this use case.
- Kamq 3y ago> Statically linking libC is problematic in various ways. Are we just talking about standard rop gadget vulnerabilities, or is there something else that's a problem with it?
- thristian 3y agoglibc, Linux's traditional libc, can dynamically load hostname resolution policies, but that only works if the executable has access to dynamic loading, i.e. if it's not a static executable. Dynamically loading hostname resolution policies doesn't happen often, but when it does happen it's a right pain to diagnose why some tools see the right hostname and other tools don't.
- henry_viii 3y agoDoesn't Deno already let us do this?
- chrisco255 3y agoBun is intended to be a drop in replacement for Node.js, with Node.js compatible APIs. Deno chose to go a different route with the design of the runtime, encouraging more modern web-native paradigms.
- hiccuphippo 3y agoDeno changed their opinion recently and will offer Node.js compatibility. Apparently it wasn't such a good idea to not be compatible on purpose.
- tracker1 3y agoI actually have mixed feelings on this one... since I think Deno's approach has been generally cleaner, but also recognize the scale of what's in NPM.
- chrisco255 3y agoDidn't realize that, thank you. I can empathize with Deno's desire to take backend JS in a more web-native direction.
- ignoramous 3y agoYes, that it does. Bun is mostly towing Deno with Zig + JSCore (and per some microbenchmarks, faster than both Node and Deno).
- brundolf 3y agoFwiw, Deno can do this too: https://deno.com/manual@v1.33.3/tools/compiler https://deno.com/manual@v1.33.3/tools/compiler
- petetnt 3y agoAnd NodeJS too https://nodejs.org/api/single-executable-applications.html https://nodejs.org/api/single-executable-applications.html
- vdfs 3y agoThere is also https://github.com/vercel/pkg https://github.com/vercel/pkg
- JonathonW 3y agoProduces smaller binaries than bun too-- one of my applications, packaged by pkg for Windows, is about 70 MB (and actually does things; this isn't a Hello World). And it compresses well (must be including library sources in the binary as plain text); in a ZIP it's about 25 MB. Still not small, but I'm not sure what Bun's doing to come out 20 MB larger than an app with actual functionality and dependencies (this one has express, sqlite, passport, bcrypt, and a bunch of others-- essentially everything you'd need for a web service).
- iansinnott 3y agoPerhaps it's specific to the applications i've built, but pkg has _ALWAYS_ given me issues. The ideal is the packaged code Just Works as if you ran it with node, and in my experience pkg does not deliver in that regard. Glad others are finding value there, but i wish it was more of a drop-in replacement for `node <script.js>`. Feels similar to `ts-node` (always having issues) and `tsx` (just works).
- freeatnet 3y agoDoes anyone know of a good comparison of these bundling methods?
- 3y ago
- bdg 3y agoIs this like a phar file?
- blowski 3y agoPhar files still need the PHP runtime installed to run them. These files have the JS runtime embedded in them.
- pier25 3y agoApparently a hello world is like 90MB. https://twitter.com/jarredsumner/status/1657765876085690368 https://twitter.com/jarredsumner/status/1657765876085690368
- bryancoxwell 3y agoWell, I do appreciate the transparency to be honest.
- VWWHFSfQ 3y agoI'm curious why that would be so big. Even my python3.10 binary + /usr/lib/python3.10 is only 30MB
- matlin 3y agoIt bundles an entire JS engine with it. I think JSC in Bun's case. V8 for Deno and Node.
- ricardobeat 3y agoThe 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.
- billywhizz 3y agoyes. 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.
- billywhizz 3y agoi just tried recompiling v0.0.2 (https://github.com/just-js/just/releases/tag/0.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. =/
- inglor 3y agoNode supports this too (experimentally) https://nodejs.org/api/single-executable-applications.html https://nodejs.org/api/single-executable-applications.html
- synergy20 3y agogolang is the most famous all-in-one-binary language with reasonable size. zig is by default static linked, it probably has the smallest binary size, smaller than static C.
- pjmlp 3y agoYeah, because compilers that produce static binaries don't exist since Macro Assemblers and FORTRAN were created. /s