A CLI version manager for the discriminating CLI connoisseur, this tool is great to install binaries both at a global level and a project level. If you are using asdf, I highly recommend this as an alternative, with the caveat of it not managing python, ruby, or other runtimes. It’s focused on CLI development tools, and providing a global or project-level version configuration that automatically installs on demand.

Aqua runs as a proxy for the invoked CLIs, which means it automatically handles installing the called tool if it’s missing, on demand, further cutting down initial setup time.

You can even use it in docker images or CI and have a single version pinned file helping the local and CI tools be similar.

It’s more secure than asdf by default.

Quick Start includes install commands to setup.

I use curl-based install mostly: Install

=== “install with brew”

  ```shell title="brew install"
  brew install aquaproj/aqua/aqua

=== “install with go”

  ```shell title="pwsh go install"
  pwsh -NoLogo -Command "go install"

=== “macOS/Linux”

  ```shell title="$HOME/.zshenv"
  export PATH="${AQUA_ROOT_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/aquaproj-aqua}/bin:$PATH"

  The options below are one for max flexibility in honoring the XDG_Directory standard; the other just assumes `.local`.

  ```powershell title="$PROFILE"
  $ENV:XDG_DATA_HOME = $ENV:XDG_DATA_HOME ? $ENV:XDG_DATA_HOME : (Join-Path $HOME '.local' 'share')

  $ENV:PATH = ([io.path]::Combine($HOME,'.local','share','aquaproj-aqua', 'bin')), $ENV:PATH -join [IO.Path]::PathSeparator
  $ENV:PATH = ([io.path]::Combine($ENV:XDG_DATA_HOME, 'aquaproj-aqua', 'bin')), $ENV:PATH -join [IO.Path]::PathSeparator

=== “windows”

  ```powershell title="Windows: System Environment Variables (Outside Process Scope)"
  [Environment]::SetEnvironmentVariable('PATH', ((Join-Path $ENV:LOCALAPPDATA 'aquaproj-aqua' 'bin') , $ENV:PATH -join [IO.Path]::PathSeparator), 'Machine')

  ```powershell title="$PROFILE.CurrentUserAllHosts"
  $ENV:PATH = ((Join-Path $ENV:LOCALAPPDATA 'aquaproj-aqua' 'bin') , $ENV:PATH -join [IO.Path]::PathSeparator)

To create these files, navigate to the directory and run aqua init && aqua init-policy.

Run aqua policy allow "${XDG_CONFIG_HOME:-$HOME/.config}/aqua/aqua-policy.yaml" to allow global tooling that’s customized.

=== “linux/darwin”

```shell title="$HOME/.zshenv"
export PATH="${AQUA_ROOT_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/aquaproj-aqua}/bin:$PATH"
export AQUA_GLOBAL_CONFIG=${XDG_CONFIG_HOME:-$HOME/.config}/aqua/aqua.yaml
# export AQUA_POLICY_CONFIG=${XDG_CONFIG_HOME:-$HOME/.config}/aqua/aqua-policy.yaml

=== “windows”

```powershell title="$PROFILE"
  $RootLocation = $ENV:AQUA_ROOT_DIR ?? (Join-Path $ENV:XDG_DATA_HOME  'aquaproj-aqua' 'bin') ?? (Join-Path "$HOME/.local/share"  'aquaproj-aqua' 'bin')
  $RootLocationWithBin = Join-Path $RootLocation 'bin'
  $ENV:PATH = $RootLocationWithBin, $ENV:PATH -join [IO.Path]::PathSeparator

Here’s an example of what I drop into the global config for managing my global default for Go and other common CLI tools.

=== “aqua.yaml”

```yaml title="${XDG_CONFIG_HOME:-$HOME/.config}/aqua/aqua.yaml"
# aqua - Declarative CLI Version Manager
  enabled: true
  require_checksum: false
  - type: standard
    ref: v4.15.0 # renovate: depName=aquaproj/aqua-registry
  - name: local
    type: local
    path: registry.yaml
  - name: golang/[email protected]
    tags: ['first']
  - name: git-town/[email protected]
  - name: golangci/[email protected]
  - name: itchyny/[email protected]
  - name: dandavison/[email protected]
  - name: junegunn/[email protected]
  - name: sharkdp/[email protected]
  - name: magefile/[email protected]
  - name: starship/[email protected]
  - name: BurntSushi/[email protected]
  - name: sharkdp/[email protected]
  - name: x-motemen/[email protected]
  - name: helm/[email protected]
  - name: kubernetes-sigs/[email protected]
  - name: kubernetes/kubectl
    version: v1.25.2
  - name: Schniz/[email protected]
  - name: ajeetdsouza/[email protected]
  - name: miniscruff/[email protected]
  - name: direnv/[email protected]
  # ... more packages here like minikube, charm tooling like gum, etc. All lazy installed `--only-link` or pre-installed with normal `aqua i`.

=== “registry.yaml”

This is the custom location for packages not in the standard registry.
While I recommend contributing upstream (it's really simple), sometimes less shareable tools for specific needs make sense to include here.

```yaml title="${XDG_CONFIG_HOME:-$HOME/.config}/aqua/registry.yaml"
- type: go_install
  name: mage-select
  description: CLI frontend for mage based on promptui.
    - mage
    - module
    - go
- type: github_release
  repo_owner: alihanyalcin
  repo_name: gomup
  asset: 'gomup_{{trimV .Version}}_{{.OS}}_{{.Arch}}.tar.gz'
  description: gomUP is a tool to keep track of outdated dependencies and upgrade them to the latest version. Designed for monorepo Go projects and Go projects that contain multiple modules.
    - gomod
    - module
    darwin: Darwin
    linux: Linux
    windows: Windows
    386: i386
    amd64: x86_64

=== “aqua-policy.yaml”

Used to allow the custom tooling that aqua can handle outside the standard packages.
For example, custom `cargo install` or `go install` packages.

```yaml title="${XDG_CONFIG_HOME:-$HOME/.config}/aqua/aqua-policy.yaml"
# aqua Policy
  - type: standard
    ref: semver(">= 3.0.0")
  - name: local
    type: local
    path: registry.yaml
  - registry: standard
  - registry: local

=== “azure pipelines”

This is focused on `ubuntu-latest` as the windows agent has some quirks not addressed in this format.
This still uses `pwsh` on the ubuntu agent to avoid me having to rework logic for 2 platforms.

```yaml title=""
- pwsh: |
    &curl -sSfL | bash -s -- -v v2.3.6
    try {
      $ENV:PATH = ([io.path]::Combine($HOME,'.local','share','aquaproj-aqua', 'bin')), $ENV:PATH -join [IO.Path]::PathSeparator
    catch {
      Write-Warning "Unable to load aqua: $($_.Exception.Message)"
    Write-Host "aqua version: $(& aqua version)"
    &aqua update-aqua
    Write-Host "aqua version (after update): $(& aqua version)"
    $env:PATH = (Join-Path $(aqua root-dir) 'bin'), $env:PATH -join [IO.Path]::PathSeparator
    Write-Host "run aqua install --tags first"
    &aqua install --tags first
    Write-Host "install remaining aqua tools"
    aqua install --tags MYCUSTOM TAG # 👈 narrow down what you invoke
    $ENV:PATH = (Join-Path $HOME '.config' @('aquaproj-aqua','bin')), $ENV:PATH -join [IO.Path]::PathSeparator
    mage # ..... 👈 invoke commands now that things are installed


(No webmentions yet.)