A lightweight, cross-platform binary manager that simplifies downloading, installing, and managing binaries without requiring root privileges.

Modern development tools are increasingly distributed as single binary releases thanks to languages like Go, Rust, and Deno. While this makes distribution easier, it creates challenges for updates and tracking.
bin solves these problems by:
sudoFor a comprehensive list, see the Tools Wiki.
bin from the releases./bin install github.com/marcosnils/bin so bin is managed by bin itselfbin ls to make sure bin has been installed correctly. You can now remove the first file you downloaded.Run these commands to install bin from scoop.
scoop bucket add extras
scoop install extras/bin
| Command | Description | Example |
|---|---|---|
bin install <repo> [path] | Install binary from GitHub or Docker | bin install github.com/cli/cli |
bin list | List installed binaries and versions | bin list |
bin update [binary...] | Update binaries (all or specified) | bin update |
bin remove <binary...> | Remove one or more binaries | bin remove gh kubectl |
bin ensure | Ensure all configured binaries are present | bin ensure |
bin pin <binary...> | Pin current version (prevent updates) | bin pin terraform |
bin unpin <binary...> | Unpin binaries (allow updates) | bin unpin terraform |
bin prune | Remove missing binaries from database | bin prune |
bin help | Show help for any command | bin help install |
Tips: if bin is unable to found the right package, try bin install -a to show all possible download options (skip scoring & filtering).
Github provider will use Github API to found releases matching your workstation specs.
At the moment, bin does only consider the latest release from Github according to the following definition:
The latest release is the most recent non-prerelease, non-draft release, sorted by the
created_atattribute. Thecreated_atattribute is the date of the commit used for the release, and not the date when the release was drafted or published.
You can however install a specific pre-release by specifying the URL for the pre-release, e.g. bin install https://github.com/bufbuild/buf/releases/tag/v0.40.0.
| Environment Variable | Mandatory | Description |
|---|---|---|
GITHUB_AUTH_TOKEN | no | set a token. The access token used with bin does not need any scopes to avoid rate limit or if you need to download from private repo** |
GHES_BASE_URL | no | github enterprise base URL (often is your GitHub Enterprise hostname). |
GHES_UPLOAD_URL | no | github enterprise upload URL (often is your GitHub Enterprise hostname). |
GHES_AUTH_TOKEN | no | github enterprise auth token similar to GITHUB_AUTH_TOKEN. |
# installs latest Kind release
bin install github.com/kubernetes-sigs/kind
# installs a specific release
bin install github.com/kubernetes-sigs/kind/releases/tag/v0.8.0
# installs latest on a specific path
bin install github.com/kubernetes-sigs/kind ~/bin/kind
# installs latest on a specific path and show all possible download options (skip scoring & filtering)
bin install -a github.com/yt-dlp/yt-dlp
or explicit
bin install --provider github github.companyname.com/custom/repo
Gitlab provider will use Gitlab API to found releases matching your workstation specs
| Environment Variable | Mandatory | Description |
|---|---|---|
GITLAB_TOKEN | yes | now gitlab enforce token usage and don't have public api, you could setup a personal access token, a GAT or a PAT |
bin install gitlab.com/gitlab-org/cli
or explicit
bin install --provider gitlab gitlab.companyname.com/custom/repo
Codeberg provider uses the Gitea/Forgejo API (GitHub-compatible) to find releases matching your workstation specs. Codeberg is a free and open-source alternative to GitHub, hosted at codeberg.org.
| Environment Variable | Mandatory | Description |
|---|---|---|
CODEBERG_TOKEN | no | set a token for authentication. Useful for rate limiting or private repos |
# installs latest mergiraf release
bin install codeberg.org/mergiraf/mergiraf
# installs a specific release
bin install codeberg.org/mergiraf/mergiraf/releases/tag/v1.0.0
# installs latest on a specific path
bin install codeberg.org/mergiraf/mergiraf ~/bin/mergiraf
or explicit
bin install --provider codeberg codeberg.org/custom/repo
Docker is also supported or any Docker client compatible runtime.
Any variable supported by Docker, see https://docs.docker.com/reference/cli/docker/
# install the `light` tag for terraform
bin install docker://hashicorp/terraform:light
# install the latest version of calico/node
bin install docker://quay.io/calico/node
For other runtime (like Podman) or for remote docker engine, simply export DOCKER_HOST envvar:
export DOCKER_HOST="unix:///path/to/unix/socket"
bin install docker://quay.io/calico/node
None.
Some projects distribute their binaries from a plain HTTP download page
instead of GitHub-style release assets. bin supports these through
dedicated HTTP providers, selected automatically by host:
bin install releases.hashicorp.com/terraform
bin install get.helm.sh
To install a specific version, use the versioned URL (the binary matching your platform is selected automatically):
bin install https://releases.hashicorp.com/terraform/1.5.7 ~/bin/terraform-1.5.7
bin install https://get.helm.sh/helm-v3.16.3-linux-amd64.tar.gz ~/bin/helm-3.16.3
Ensure go is present in your PATH.
bin runs go install <path>@<ref> into a private GOBIN, reads the
installed version from the binary's build info and copies it to your dest.
Your own GOPATH/bin or GOBIN is not touched.
The path can point at a package inside a module (for example cmd/<name>),
go resolves the containing module. The ref defaults to latest and can be a
tag, branch or commit; bin update follows that ref, so @main tracks the
branch and @v0.1.8 stays put.
bin install goinstall://github.com/jrhouston/tfk8s@v0.1.8
bin install goinstall://github.com/googleapis/api-linter/v2/cmd/api-linter
Version resolution goes through the go toolchain, so GOPROXY, GOPRIVATE
and GOFLAGS are honoured.
bin maintains a configuration file to track installed binaries.
Path to the configuration directory respects the XDG Base Directory specification using the following strategy:
BIN_CONFIG is set$HOME/.bin/config.json exists and return $HOME/.binXDG_CONFIG_HOME is set, return $XDG_CONFIG_HOME/bin$HOME/.config exists, return $home/.config/bin$HOME/.bin/Same than linux but uses %USERPROFILE% without XDG_CONFIG_HOME.
By default, bin stores binaries in:
~/.local/bin/%LOCALAPPDATA%\bin\Ensure this directory is in your $PATH.
There are some bugs, and the code has not been tested due to a lack of time, but contributions are welcome, and Iβll be happy to discuss and review them.
# Clone the repository
git clone https://github.com/marcosnils/bin.git
cd bin
# Clean and init
make clean download
# Run syntax check
make lint verify
# Run tests
make test
# Build from source
make build
This project is licensed under the MIT License - see the LICENSE file for details.
bin started as an idea given the popularity of single binary releases due to the surge of languages like Go, Rust, Deno, etc which can easily produce dynamically and statically compiled binaries.
I found myself downloading binaries (or tarballs) directly from VCS (Github mostly) and then it was hard to keep control and update such dependencies whenever a new version was released. So, with the objective to solve that problem and also looking for something that will allow me to get the latest releases, I created bin.
In addition to that, I was also looking for something that doesn't require sudo or root privileges to install these binaries as downloading, making them executable and storing it somewhere in your PATH would be sufficient.
After I finished the first MVP, a friend pointed out that brew was now supported in linux which almost made me abandon the project. After checking out brew (never been an osx user), I found it a bit bloated and seems to be doing way more than what I'm actually needing. So, I've decided to continue bin and hopefully add more features that could result useful to someone else.
Go
99.2%
A lightweight, cross-platform binary manager that simplifies downloading, installing, and managing binaries without requiring root privileges.

Modern development tools are increasingly distributed as single binary releases thanks to languages like Go, Rust, and Deno. While this makes distribution easier, it creates challenges for updates and tracking.
bin solves these problems by:
sudoFor a comprehensive list, see the Tools Wiki.
bin from the releases./bin install github.com/marcosnils/bin so bin is managed by bin itselfbin ls to make sure bin has been installed correctly. You can now remove the first file you downloaded.Run these commands to install bin from scoop.
scoop bucket add extras
scoop install extras/bin
| Command | Description | Example |
|---|---|---|
bin install <repo> [path] | Install binary from GitHub or Docker | bin install github.com/cli/cli |
bin list | List installed binaries and versions | bin list |
bin update [binary...] | Update binaries (all or specified) | bin update |
bin remove <binary...> | Remove one or more binaries | bin remove gh kubectl |
bin ensure | Ensure all configured binaries are present | bin ensure |
bin pin <binary...> | Pin current version (prevent updates) | bin pin terraform |
bin unpin <binary...> | Unpin binaries (allow updates) | bin unpin terraform |
bin prune | Remove missing binaries from database | bin prune |
bin help | Show help for any command | bin help install |
Tips: if bin is unable to found the right package, try bin install -a to show all possible download options (skip scoring & filtering).
Github provider will use Github API to found releases matching your workstation specs.
At the moment, bin does only consider the latest release from Github according to the following definition:
The latest release is the most recent non-prerelease, non-draft release, sorted by the
created_atattribute. Thecreated_atattribute is the date of the commit used for the release, and not the date when the release was drafted or published.
You can however install a specific pre-release by specifying the URL for the pre-release, e.g. bin install https://github.com/bufbuild/buf/releases/tag/v0.40.0.
| Environment Variable | Mandatory | Description |
|---|---|---|
GITHUB_AUTH_TOKEN | no | set a token. The access token used with bin does not need any scopes to avoid rate limit or if you need to download from private repo** |
GHES_BASE_URL | no | github enterprise base URL (often is your GitHub Enterprise hostname). |
GHES_UPLOAD_URL | no | github enterprise upload URL (often is your GitHub Enterprise hostname). |
GHES_AUTH_TOKEN | no | github enterprise auth token similar to GITHUB_AUTH_TOKEN. |
# installs latest Kind release
bin install github.com/kubernetes-sigs/kind
# installs a specific release
bin install github.com/kubernetes-sigs/kind/releases/tag/v0.8.0
# installs latest on a specific path
bin install github.com/kubernetes-sigs/kind ~/bin/kind
# installs latest on a specific path and show all possible download options (skip scoring & filtering)
bin install -a github.com/yt-dlp/yt-dlp
or explicit
bin install --provider github github.companyname.com/custom/repo
Gitlab provider will use Gitlab API to found releases matching your workstation specs
| Environment Variable | Mandatory | Description |
|---|---|---|
GITLAB_TOKEN | yes | now gitlab enforce token usage and don't have public api, you could setup a personal access token, a GAT or a PAT |
bin install gitlab.com/gitlab-org/cli
or explicit
bin install --provider gitlab gitlab.companyname.com/custom/repo
Codeberg provider uses the Gitea/Forgejo API (GitHub-compatible) to find releases matching your workstation specs. Codeberg is a free and open-source alternative to GitHub, hosted at codeberg.org.
| Environment Variable | Mandatory | Description |
|---|---|---|
CODEBERG_TOKEN | no | set a token for authentication. Useful for rate limiting or private repos |
# installs latest mergiraf release
bin install codeberg.org/mergiraf/mergiraf
# installs a specific release
bin install codeberg.org/mergiraf/mergiraf/releases/tag/v1.0.0
# installs latest on a specific path
bin install codeberg.org/mergiraf/mergiraf ~/bin/mergiraf
or explicit
bin install --provider codeberg codeberg.org/custom/repo
Docker is also supported or any Docker client compatible runtime.
Any variable supported by Docker, see https://docs.docker.com/reference/cli/docker/
# install the `light` tag for terraform
bin install docker://hashicorp/terraform:light
# install the latest version of calico/node
bin install docker://quay.io/calico/node
For other runtime (like Podman) or for remote docker engine, simply export DOCKER_HOST envvar:
export DOCKER_HOST="unix:///path/to/unix/socket"
bin install docker://quay.io/calico/node
None.
Some projects distribute their binaries from a plain HTTP download page
instead of GitHub-style release assets. bin supports these through
dedicated HTTP providers, selected automatically by host:
bin install releases.hashicorp.com/terraform
bin install get.helm.sh
To install a specific version, use the versioned URL (the binary matching your platform is selected automatically):
bin install https://releases.hashicorp.com/terraform/1.5.7 ~/bin/terraform-1.5.7
bin install https://get.helm.sh/helm-v3.16.3-linux-amd64.tar.gz ~/bin/helm-3.16.3
Ensure go is present in your PATH.
bin runs go install <path>@<ref> into a private GOBIN, reads the
installed version from the binary's build info and copies it to your dest.
Your own GOPATH/bin or GOBIN is not touched.
The path can point at a package inside a module (for example cmd/<name>),
go resolves the containing module. The ref defaults to latest and can be a
tag, branch or commit; bin update follows that ref, so @main tracks the
branch and @v0.1.8 stays put.
bin install goinstall://github.com/jrhouston/tfk8s@v0.1.8
bin install goinstall://github.com/googleapis/api-linter/v2/cmd/api-linter
Version resolution goes through the go toolchain, so GOPROXY, GOPRIVATE
and GOFLAGS are honoured.
bin maintains a configuration file to track installed binaries.
Path to the configuration directory respects the XDG Base Directory specification using the following strategy:
BIN_CONFIG is set$HOME/.bin/config.json exists and return $HOME/.binXDG_CONFIG_HOME is set, return $XDG_CONFIG_HOME/bin$HOME/.config exists, return $home/.config/bin$HOME/.bin/Same than linux but uses %USERPROFILE% without XDG_CONFIG_HOME.
By default, bin stores binaries in:
~/.local/bin/%LOCALAPPDATA%\bin\Ensure this directory is in your $PATH.
There are some bugs, and the code has not been tested due to a lack of time, but contributions are welcome, and Iβll be happy to discuss and review them.
# Clone the repository
git clone https://github.com/marcosnils/bin.git
cd bin
# Clean and init
make clean download
# Run syntax check
make lint verify
# Run tests
make test
# Build from source
make build
This project is licensed under the MIT License - see the LICENSE file for details.
bin started as an idea given the popularity of single binary releases due to the surge of languages like Go, Rust, Deno, etc which can easily produce dynamically and statically compiled binaries.
I found myself downloading binaries (or tarballs) directly from VCS (Github mostly) and then it was hard to keep control and update such dependencies whenever a new version was released. So, with the objective to solve that problem and also looking for something that will allow me to get the latest releases, I created bin.
In addition to that, I was also looking for something that doesn't require sudo or root privileges to install these binaries as downloading, making them executable and storing it somewhere in your PATH would be sufficient.
After I finished the first MVP, a friend pointed out that brew was now supported in linux which almost made me abandon the project. After checking out brew (never been an osx user), I found it a bit bloated and seems to be doing way more than what I'm actually needing. So, I've decided to continue bin and hopefully add more features that could result useful to someone else.
Go
99.2%