bine manages external binary tools required by a development project.
You declare the tools your project needs in .bine.json or .bine.toml.
bine downloads them into a project-scoped cache and gives you a consistent
way to run them. This keeps versions aligned across local development and CI
without polluting global system paths.
- Project-scoped: Each project gets its own binary cache.
- Reproducible: Pin exact tool versions when you need deterministic builds.
- Flexible: Install tools from GitHub releases or Go packages.
- Simple to use: Run tools with
bine runor add them toPATHwithbine env.
Download the archive for your platform from the releases page and place the
binary somewhere in your PATH.
For example, on Linux amd64:
curl -L -o ~/.local/bin/bine \
https://github.com/artefactual-labs/bine/releases/download/v0.21.0/bine_0.21.0_linux_amd64
chmod +x ~/.local/bin/bineChoose the release asset that matches your OS and architecture.
If you already manage development tools through Go, you can add bine as a Go
tool:
go get -tool github.com/artefactual-labs/bine@latestIn that setup, invoke it as go tool bine ....
Create a .bine.json or .bine.toml file in your project root.
This is the JSON variant (.bine.json):
This is the TOML variant (.bine.toml):
project = "my-awesome-project"
[[bins]]
name = "golangci-lint"
url = "https://github.com/golangci/golangci-lint"
version = "2.0.2"
asset_pattern = "{name}-{version}-{goos}-{goarch}.tar.gz"Install the configured tools:
bine syncRun a managed binary:
bine run golangci-lint --helpOr add the project bin directory to your shell PATH:
# Bash or Zsh
source <(bine env --shell=bash)
# Fish
bine env --shell=fish | source
# POSIX shells
eval "$(bine env --shell=sh)"After that, you can call the tool directly:
golangci-lint --helpThe .bine.json or .bine.toml file defines the binaries available in the
current project.
{
"project": "example-project",
"bins": [
{
"name": "jq",
"version": "1.8.0",
"url": "https://github.com/jqlang/jq",
"asset_pattern": "{name}-{goos}-{goarch}",
"tag_pattern": "{name}-{version}",
"modifiers": {
"goos": {
"darwin": "macos"
}
}
},
{
"name": "govulncheck",
"go_package": "golang.org/x/vuln/cmd/govulncheck",
"version": "latest"
}
]
}Each entry in bins uses one installation strategy:
- GitHub release assets, using fields such as
urlandasset_pattern - Go packages, using
go_package
bine includes built-in defaults for common GitHub release assets. When url
matches a known source, bine can fill repeated fields such as asset_pattern,
tag_pattern, and modifiers. The bin name is only the local executable name;
it is not used to choose library defaults. Any fields you set explicitly still
take precedence.
[[bins]]
name = "go-mod-outdated"
url = "https://github.com/psampaz/go-mod-outdated"
version = "0.9.0"See the known binaries library for the current built-in templates.
When go_package is used, version supports two modes:
- Pinned mode: set
versionto a specific release such as"v0.30.0"or"0.30.0". - Latest-tracking mode: omit
version, or set it to"latest".
For example, this go install command:
go install golang.org/x/vuln/cmd/govulncheck@latestmaps to:
{
"name": "govulncheck",
"go_package": "golang.org/x/vuln/cmd/govulncheck",
"version": "latest"
}Typical workflow:
bine syncinstalls the current latest version.bine list --outdatedchecks whether the installed resolved version is now behind.bine upgrade govulncheckrefreshes that tool if a newer release exists.
If you need to rebuild cached binaries without changing their configured
versions, for example after switching Go toolchains, use bine get --force <NAME>, bine sync --force, or bine reinstall.
bine upgrade without an argument upgrades every configured binary.
bine keeps track of the exact version installed from latest, so it can
later report whether that cached binary is stale without rewriting the config
file.
Use template variables in asset_pattern to match upstream release filenames.
| Variable | Description | Example |
|---|---|---|
{name} |
Binary name from the config. |
jq |
{version} |
Version without a v prefix. |
1.8.0 |
{goos} |
Go OS identifier (runtime.GOOS). |
linux, darwin |
{goarch} |
Go architecture identifier (runtime.GOARCH). |
amd64, arm64 |
{os} |
System OS name (uname -s). |
Linux, Darwin |
{arch} |
System architecture (uname -m). |
x86_64, arm64 |
{triple} |
Rust-style target triple. | x86_64-unknown-linux-gnu |
Combine asset_pattern with modifiers when an upstream project uses
non-standard naming.
tag_pattern controls how Git tags are constructed when resolving GitHub
releases. The default is v{version}.
| Variable | Description | Example |
|---|---|---|
{name} |
Binary name from the config. |
jq |
{version} |
Version without a v prefix. |
1.8.0 |
Use bine --help for the full command reference.
Core subcommands:
bine config get <KEY>: Print a configuration value.bine env: Output shell code that adds the project bin directory toPATH.bine get [--force] <NAME>: Download one binary and print its path.bine list: List configured binaries.bine path: Print the current project bin directory.bine reinstall: Reinstall all configured binaries. Alias forbine sync --force.bine run <NAME> [ARGS...]: Download a binary and execute it.bine sync [--force]: Install all binaries defined in the project config file.bine upgrade [NAME]: Upgrade one binary or all configured binaries.bine version: Print the currentbineversion.
Global flags:
-v, --verbose: Increase log verbosity. Repeat as-vvor-vvv;-vvvis the highest shorthand level we expect to need in practice.--verbosity=N: Set the log verbosity level explicitly.--cache-dir: Override the cache directory location.--github-api-token: Provide a GitHub API token for authenticated requests.
bine uses the GitHub REST API to inspect releases and download binaries from
GitHub repositories. Unauthenticated requests are limited to 60 requests per
hour.
You can pass a token either with --github-api-token or through the
BINE_GITHUB_API_TOKEN environment variable:
export BINE_GITHUB_API_TOKEN=your_token_here
bine list --outdatedSee the examples directory for integration patterns:
examples/fishfor Fish shell helpersexamples/makefor Make-based workflowsexamples/justfor Just-based workflows
go get -tool is useful for Go module-based binaries, but it does not cover
non-Go tools such as jq or shfmt.
That said, go get -tool is a good way to install bine itself in Go-based
projects:
go get -tool github.com/artefactual-labs/bine@latest
go tool bine pathasdf and mise are broader tools with more features. bine stays focused
on lightweight, project-scoped binary management for development workflows.
Nix provides fully reproducible and isolated environments. bine is narrower:
it focuses on managing development binaries with less setup and a smaller
surface area.
For one-off use, this is enough:
bine env --shell=fish | sourceIf you install bine as a Go tool instead, use:
go tool bine env --shell=fish | sourceFor a reusable helper function, see examples/fish.
{ // Comments are supported. "project": "my-awesome-project", "bins": [ { "name": "golangci-lint", "url": "https://github.com/golangci/golangci-lint", "version": "2.0.2", "asset_pattern": "{name}-{version}-{goos}-{goarch}.tar.gz" } ] }