Go Binaries is an open-source server allowing non-Go users to quickly install tools written in Golang, without installing the Go compiler or a package manager — all you need is curl. Let's take a look at how it works, and how to use it!

Freeing up time for the authors of OSS

The authors of Go programs typically pre-compile and upload dozens of binaries for each release, after which the users must find the right binary for their system, download, and install it.

Example of the build artifacts required for Up v0.7.2

There are tools which can help automate this process, such as GitHub Actions, but it's a step most smaller tools could avoid all-together. The Go Binaries approach is to build binaries for your command(s) on-demand — just drop this snippet in your Readme's installation documentation and you're done.

$ curl -sf https://gobinaries.com/<username>/<repo> | sh

Let's check out a real-world example.

Installing programs

Suppose you want to install the fantastic "hey" HTTP benchmarking tool, you can install the latest release with the following command. In a few seconds you'll have the hey command available on your machine — installed to /usr/local/bin by default.

$ curl -sf https://gobinaries.com/rakyll/hey | sh

  ==> Downloading github.com/rakyll/hey@master
  ==> Resolved version master to v0.1.3
  ==> Downloading binary for darwin amd64
  ==> Installing hey to /usr/local/bin
  ==> Installation complete

$ hey https://apex.sh

Response time histogram:
  0.008 [1]   |■
  0.018 [76]  |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  0.027 [73]  |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
  0.036 [0]   |


In scenarios such as continuous integration you may want to lock down a particular version to prevent any surprises using SemVer. Go Binaries currently supports the following syntax for matching versions:

  • Exact version: v1.2.3, 1.2.3
  • Wildcards: v1.x, v1.2.x, 1.x, 1.2.x
  • Wildcards (implicit): v1, v1.2, 1.2
  • Leading v is optional, regardless of the Git tag

Here are a few examples:

$ curl -sf https://gobinaries.com/rakyll/[email protected] | sh
$ curl -sf https://gobinaries.com/rakyll/[email protected] | sh
$ curl -sf https://gobinaries.com/rakyll/[email protected] | sh
$ curl -sf https://gobinaries.com/rakyll/[email protected] | sh

The path provided to gobinaries.com should be the full path to your main package, for example, my project staticgen has the main in cmd/staticgen/main.go, so it is installed as the following:

$ curl -sf https://gobinaries.com/tj/staticgen/cmd/staticgen | sh

Specifying the output directory

By default, binaries are installed to /usr/local/bin, however, you can change the target directory using the PREFIX environment variable. This is particularly useful in continuous integration, or for installing tools to Docker containers.

$ curl -sf https://gobinaries.com/rakyll/hey | PREFIX=. sh
$ ./hey https://apex.sh

If the directory doesn't exist it will be created.

How the server works

The request for a package resolves the requested version to a Git tag, and responds with a shell script which should be piped to sh. This is necessary because the server needs to determine your operating system and architecture to cross-compile the Go binary appropriately.

$ curl -sf https://gobinaries.com/rakyll/hey | sh

The shell script performs a second request to gobinaries.com to fetch and install the actual binary, with the OS, architecture, and a concrete version number. If the package was not previously built, it will be cross-compiled be stored in Google Cloud Storage for up to 30 days, and cached in a CDN. This secondary request looks like this:


Open source

As I mentioned this is a free hosted service, however, the source is also available over at tj/gobinaries if you'd like to run your own instance or contribute to the project.

Finally a big thank you to CTO.ai and my GitHub Sponsors for sponsoring the time to create this project! I wouldn't have the time to work on projects like this without your support.