Hacker News new | ask | show | jobs
by jumpyjumps 1255 days ago
I'm begging you, just use a language that compiles to a single binary. It can self update in place, be easily installed on developer machines and CI pipelines without requiring a whole additional toolchain in every container. Google, Heroku, AWS, Shopify all do and it's an awful developer experience.
5 comments

Rust is amazing for CLIs (Go potentially as well, too little experience with that personally!), but if you're already quite comfortable with JS & have existing investment in it for CLI or related code, then ´npx <tool> ...` while asking the user to install Node (or Bun) is an acceptable tradeoff in most cases. Updating via npm is also easy enough for users, though it's not self-updating of course, but basically no CLI will do that fully automatically for you. Not even Cloud SDK CLIs. And for good reason.
Exactly, I get that they initially used Ruby given the whole company is build on it. But overhauling the CLI and NOT going for a single binary is beyond me.
Seems odd on the face of it. They say it is because the CLI already depended on Node and they couldn't escape it. So, they moved from depending on Ruby and Node to just Node I guess.
What's the mechanism for self-updating in place? Something more intelligent than just downloading and copying the file over itself? A running program itself is a copy of the file on disk, I think. So that sounds fine. But this still depends on getting permissions right though I think. Also, does a binary always know where it lives (across Win/Mac/Linux)?
Download-and-copy is the way. A single binary CLI can just copy over itself and exec into the new version. You can preserve the permissions of the original file.

With scripting-language CLIs, you either have to deal with the module install process or use an external packaging solution.

This works pretty good, but we've ran into issues where the downloaded file isn't code signed and then this becomes a big issue. AFAIK, if this is a public CLI then homebrew will codesign for you, if you are distributing a private CLI then you need to solve the code signing issue yourself. Not many blog posts on how to handle this...
> I'm begging you, just use a language that compiles to a single binary. It can self update in place

Is there a library that does self updating in place for binaries? Go is the langage that comes to mind when talking about single binary, so maybe a go library?

Maybe check out https://github.com/keygen-sh/keygen-go? Let’s you add auto upgrades to any free or commercial Go app (with support for licensing too).

(I’m the founder of the licensing API.)

Huh? To run a node application, you need node installed on the container, as well as the JS files. Is that a big deal?
You don't even need that: https://github.com/vercel/pkg.

I think there are equivalents in the Python ecosystem.

I have used PyInstaller for this before, which has the major caveat of it not being a cross-platform solution. You can only build binaries for the platform you're currently on. However, you can work around this by configuring GitHub Actions to build binaries for you for Windows, macOS (x86) and Linux.
Yes, because now I need to install node, probably run npm install, etc…
there's no npm install and there's no etc.

All the files needed to run a node application are in node_modules. If node is on the container, you can just rsync the scripts.

I think you're comparing distributing stand alone binaries, vs distributing the source code for a node app, and then installing its dependencies, and maybe doing some transpiling. That's not a fair comparison.