binary-install

1.1.0 • Public • Published

🦀 binary-install

Install .tar.gz binary applications via npm

Installation

binary-install is meant to be a devDependency of the npm package for the binary you would like to distribute.

After creating your package.json with npm init or some other method, you should run the following:

npm i --save-dev binary-install

Usage

If you want, you can check out the example package to get a feel for things before reading the following, up to you.

Intro Concepts

binary-install provides a Binary class that allows you to download a tarball containing a binary and extract it to the standard location for node binaries.

You could create an install.js file that looks something like this:

#!/usr/bin/env node

const { Binary } = require("binary-install");
let binary = new Binary('my-binary', 'https://example.com/binary/tar.gz')
binary.install();

(note: the shebang at the top of the file lets your shell know that this script should be run with the node runtime.)

And then in your package.json, you would add the following:

{
  ...
  "scripts": {
    "postinstall": "node ./install.js"
  }
  ...
}

Then, things like this would just work in your local directory!

npm i && npx my-binary --version
1.0.0

You need one more thing before your package is ready to distribute. Make a run.js file that looks like this:

#!/usr/bin/env node

const { Binary } = require("binary-install");
let binary = new Binary('my-binary', 'https://example.com/binary/tar.gz')
binary.run();

And then in your package.json, add the following:

{
  ...
  "bin": {
    "my-binary": "run.js"
  }
  ...
}

Real-world usage

Unfortunately, it's never quite as simple as the above example. You likely want to be able to make changes to your binary and release new versions. You also likely want to distribute on multiple platforms. This means that you'll probably need something that dynamically builds your tarball endpoint with that information. A pretty straightforward example of how you can achieve this can be found here. You probably want to just clone this repo and take that package as your starting point, just renaming everything along the way, it should get you pretty far.

Advanced Usage

Any arguments you pass to the install() method will be used to configure Axios when downloading the binary. This is useful for downloading from a private repo when you have to set an Authorization header or if you need to do weird things like issue a POST instead of a GET to retrieve your binary from some endpoint.

Overriding the base install directory

You may want to override the base installation directory. To do so, you can pass a third parameter to the Binary constructor to specify installDirectory, like so:

  return new Binary("my-binary", "https://example.com/my-binary/macos-arm/v1.0.0.tar.gz", {
    installDirectory: join(__dirname, ".my-custom-binary-location")
  });

Distribution

Now that you have cross-platform downloads working, it's time to distribute your tool! You should publish your package to npm just like normal, and then you should document how to install your tool for your end users. There are generally two approaches you can take to do this.

Local Installs (recommended)

After you publish your package to npm, others can run npx my-binary to install and run you binary, or you can recomment that they install your binary as a devDependency by running npm i --save-dev my-binary.

Global Installs (not recommended)

You can also recommend that they run npm i -g my-binary if your binary is not project-specific and is only used by indivdual end users and it is not likely to need to be part of a given project (this is very rare for JavaScript tools). This last approach is a bit more fraught than local installs. This is because folks will likely run into the notorious EACCES permissions error that plagues npm global installs. These errors only occur if your end users do not use a node version manager like volta or nvm, but I've found that most people do not use these and instead install node from their website (which is a totally reasonable thing to do). If you do want people to install your tool globally, and you recommend that they do so, you should prepare to field a whole bunch of issues and have a very bad time 🙃. And the not so great news is that unless Node fundamentally changes their distribution strategy, there's nothing you can do other than tell people to install a version manager!

History

I originally created this package after refactoring a bit of code that @xtuc worked on to distribute the first versions of Wrangler on npm. I now work on Rover at Apollo and we also needed to distribute binaries on npm. I knew that the first version of binary-install that Wrangler was using caused a whole slate of issues for the project. I didn't want to repeat the same mistakes at Apollo. I also knew that Cloudflare's maintenance bandwidth was super low at the time because they were shipping cool stuff like Cloudflare Pages and Durable Objects. Since I still had publishing rights to the official npm package, I forked the project to fix up a few of its problems, and the histories of the two repositories have drifted quite a bit. Cloudflare has made a few changes to their repository, and that package is published to @cloudflare/binary-install, but I retain control over the nominal binary-install package. And now you know!

Readme

Keywords

Package Sidebar

Install

npm i binary-install

Weekly Downloads

187,076

Version

1.1.0

License

MIT

Unpacked Size

11.7 kB

Total Files

4

Last publish

Collaborators

  • averyharnish