Skip to main content
Skip to main content

b install

Install binaries and sync environment files. If no arguments are given, b installs all binaries and syncs all envs from the b.yaml configuration file. You can also install specific binaries or env files on-the-fly.

Alias

  • i

Usage

b install [binary|env...] [flags]

Examples

Install all from config

If a b.yaml file is present, this command will install all binaries and sync all env files listed in it.

b install

Install a specific binary

Install the latest version of a specific binary.

b install jq

Install a specific version

Append @<version> to the binary name to install a specific version.

b install jq@jq-1.7

Install any GitHub release

Use a full provider reference to install any binary from GitHub releases.

# Install latest release
b install github.com/derailed/k9s

# Install specific version
b install github.com/sharkdp/bat@v0.24.0

Install and add to config

Use the --add flag to install a binary and simultaneously add it to your b.yaml.

b install --add kubectl

Force an installation

Use the --force flag to overwrite an existing binary.

b install --force jq

Install with an alias

Use the --alias flag to install a binary under a different name. This is useful when you want to use a custom name for a binary while still using the original binary's implementation.

b install --alias envsubst renvsubst

This installs renvsubst but makes it available as envsubst. The alias binary will:

  • Download and install the original binary (renvsubst)
  • Create the alias binary file (envsubst)
  • Work with all commands like version detection and execution
  • Show in listings with the alias relationship: renvsubst (envsubst)

You can combine --alias with other flags:

# Install with alias and add to config
b install --alias envsubst --add renvsubst

# Install specific version with alias
b install --alias myenvsubst renvsubst@v0.10.0

Sync environment files (SCP syntax)

Use SCP-style syntax to sync files from upstream git repositories:

# Sync files from a git repo to a local directory
b install github.com/org/infra:/manifests/base/** ./base

# Pin a version and sync
b install github.com/org/infra@v2.0:/manifests/hetzner/** ./hetzner

# Add to b.yaml and sync
b install --add github.com/org/infra@v2.0:/manifests/base/** ./base

The SCP syntax is: <repo>[@<version>]:/<glob> [<dest>]

  • repo — A git-cloneable reference (e.g., github.com/org/repo)
  • version (optional) — A git tag, branch, or commit to pin
  • glob — A file pattern to match in the repository (e.g., manifests/**)
  • dest (optional) — Local directory for the synced files; defaults to the matched path structure

Install from SSH repos

Use SSH URLs for private repositories (requires ssh-agent):

# Binary from SSH repo
b install "git@github.com:org/private-repo:bin/tool"

# Env sync from SSH repo (in b.yaml)
# git@github.com:org/infra:
# files:
# manifests/**:
# dest: manifests/

Install from local repos

# Binary from local repo
b install "git:///home/user/myrepo:bin/tool"
b install "git://../../shared-repo:scripts/deploy.sh"

Install from container images

Use docker:// to pull from a local container runtime, or oci:// to pull daemonless from any OCI registry (Docker Hub, ghcr.io, quay.io, private).

# docker:// — requires a running docker/podman/nerdctl
b install docker://alpine/helm
b install docker://docker@cli # tag via @ (docker:cli image)
b install docker://docker@cli:/usr/local/bin/docker # explicit in-container path

# oci:// — daemonless; works in CI containers without docker
b install oci://ghcr.io/org/img@v1
b install oci://docker@cli:/usr/local/bin/docker

The syntax is: <docker://|oci://><image>[@<tag>][:/<path-in-image>]

  • image — An image reference, including optional registry (e.g., alpine, ghcr.io/org/img)
  • tag (optional, after @) — Image tag; defaults to latest. Use @ consistently with every other b provider rather than docker's native image:tag syntax
  • path (optional, after :/) — Absolute path to the binary inside the image. When omitted, b searches /usr/local/bin, /usr/bin, /bin, and /app for a file named after the image's last segment

The leading / on the path disambiguates it from an image:tag pasted from docker documentation. For private registries, oci:// reads credentials from ~/.docker/config.json (same as docker login); see the authentication page.

Post-install hooks

Run a shell command after a binary is installed or updated. The hook only fires when the on-disk binary actually changed — not on no-op skips or --dry-run.

# Add a binary with a post-install hook
b install --add github.com/arg-sh/argsh --on-post 'argsh builtin ${B_EVENT}'

# The hook is saved to b.yaml so it runs on future updates too

The hook receives these environment variables:

VariableDescriptionExample
B_EVENTinstall or updateinstall
B_NAMEBinary nameargsh
B_VERSIONVersion being installedv0.6.6
B_FILEAbsolute path to the binary/project/.bin/argsh

In b.yaml:

binaries:
github.com/arg-sh/argsh:
onPost: argsh builtin ${B_EVENT}
kubectl:
onPost: kubectl completion bash > .completions/kubectl.bash

Hooks are POSIX shell commands (run via sh -c), executed in the project root directory — so relative paths like .completions/... resolve from there. Non-zero exit produces a warning but does not fail the install. Output goes to stderr so it doesn't interfere with progress bars. Hooks are also skipped during b update --dry-run and --plan-json.

Flags

FlagDescription
--addAdd binary/env to b.yaml during install
--aliasInstall binary under a different name
--fixPin the specified version in b.yaml
--on-postShell command to run after install/update (saved with --add)
-h, --helphelp for install

Global Flags

FlagDescription
-c, --config stringPath to configuration file (current: /home/fentas/github/fentas/b/.bin/b.yaml)
--forceForce operations, overwriting existing binaries
-q, --quietQuiet mode
-v, --versionPrint version information and quit
Was this section helpful?