# atmos toolchain install

Install CLI tools required by your Atmos components, commands, and workflows. This command downloads and sets up the exact tool versions specified in your toolchain configuration, ensuring consistent execution across your team.

## Usage

Execute the `toolchain install` command like this:

```shell
atmos toolchain install
```

## Examples

```shell
# Install a single tool
atmos toolchain install terraform@1.9.8
atmos toolchain install hashicorp/terraform@1.5.0

# Install multiple tools in a single command
atmos toolchain install opentofu@1.6.0 tflint@0.50.0 kubectl@1.29.0
atmos toolchain install terraform helm kubectl tflint

# Limit this batch to two concurrent installs
atmos toolchain install --max-concurrency 2 opentofu@1.6.0 tflint@0.50.0 kubectl@1.29.0

# Install all tools from .tool-versions file
atmos toolchain install
```

## Arguments

- **`tool@version...` (optional)** — One or more tools to install from the registry. Each tool can be a short name (alias) or full `owner/repo` format.
  If omitted, installs all tools from `.tool-versions` file.

  Examples: `terraform@1.9.8`, `hashicorp/terraform@1.5.0`, `kubectl@1.28.0`

## Flags

- **`--default`  (optional)** — Set installed version as default (front of .tool-versions)
- **`--reinstall` (optional)** — Reinstall even if already installed
- **`--max-concurrency` (optional)** — Maximum number of tools to install concurrently. The default is `4`.
  Use a positive integer; values lower than `1` are rejected. This option
  applies when installing multiple explicit tools or all tools from
  `.tool-versions`.

## Parallel Install Configuration

Independent tools in a batch install run concurrently, while Atmos coordinates
shared downloads, extraction directories, version files, and lockfiles safely.
Set a project default in `atmos.yaml`, or override it for a single command:

```yaml
toolchain:
  max_concurrency: 4
```

```shell
ATMOS_TOOLCHAIN_MAX_CONCURRENCY=6 atmos toolchain install
atmos toolchain install --max-concurrency 8
```

Concurrency is resolved in this order: `--max-concurrency`,
`ATMOS_TOOLCHAIN_MAX_CONCURRENCY`, `toolchain.max_concurrency`, then the
default of `4`.

## Frozen Installs

Enable frozen mode in CI and security-sensitive environments. Prepare, review, and commit the
lockfile for the required tools and platforms first. Set `toolchain.frozen_lock_file: true` in
`atmos.yaml`, or enable it for a CI command:

```shell
ATMOS_TOOLCHAIN_FROZEN_LOCK_FILE=true atmos toolchain install
```

Every requested version must have a URL and checksum for the current platform in the existing
lockfile, including tools whose binaries are already cached. Missing entries and checksum
mismatches fail. Frozen installation leaves `.tool-versions` and the artifact lockfile unchanged.

Ordinary installs record missing lock entries after successful extraction and preserve existing
matching entries. Automatic installs triggered by commands, dependencies, proxies, or Atmos
version switching do not change `.tool-versions`.

See [toolchain lockfile configuration](/cli/configuration/toolchain#automatic-installation-and-lockfiles)
for paths, lock generation, and frozen-mode limitations.

## How Tools Are Installed on Disk

Atmos installs each tool under a version-specific directory
(`<install_path>/bin/<owner>/<repo>/<version>/`) and adapts the on-disk layout to
the shape of the downloaded archive:

- **Single-binary tools** (for example `jq`, `terraform`, `kubectl`) are placed
  directly in the version directory as a flat executable.
- **Multi-file ("onedir") tools** (for example `aws/aws-cli` and `nodejs/node`)
  ship a binary together with runtime siblings — a bundled language runtime,
  shared libraries, or `node_modules`. For these, Atmos preserves the complete
  extracted archive under a `.pkg` subdirectory and records each registry
  entrypoint's real path (such as `aws`, `node`, `npm`, `npx`) in a small sidecar
  manifest. This keeps each executable next to the files it needs at runtime,
  matching how the upstream `aqua` CLI installs the same packages.

Atmos does not create symlinks to expose these entrypoints — a design choice
used consistently across Atmos's install/provisioning code. `which`
resolves directly to the real, nested path (for example
`.../24.18.0/.pkg/node-v24.18.0-darwin-arm64/bin/node`), and
[`atmos toolchain env`](/cli/commands/toolchain/env),
[`exec`](/cli/commands/toolchain/exec), and
[`which`](/cli/commands/toolchain/which) all resolve it the same way — including
every command a multi-command package exposes, whose directories are all added
to `PATH`. Because exposure needs no symlink, this works identically on macOS,
Linux, and Windows with no elevated privileges or Developer Mode required.

The only symlinks a onedir install may contain are ones the upstream archive
itself ships (for example Node's `npm`, which the archive links relatively as
`../lib/node_modules/...` on Unix). Atmos recreates each such link inside the
preserved `.pkg` tree after extraction, through a single validated step, so the
tool functions identically to how it would if installed from its original
archive; the links are never created by Atmos's exposure logic. Each link is
reproduced with the archive's **original relative target**, so it resolves
relative to the link's own directory and works regardless of whether the
install path is absolute or relative (such as `.tools`). The link's resolved
target is still validated to stay inside the `.pkg` tree.

On Windows, where creating a symlink normally requires Developer Mode or
elevated privilege, an archive's own **file** symlink is reproduced as a hard
link (or a copy if hard-linking is unavailable), so packages that ship such
links still install without elevation. Archives that ship **directory**
symlinks remain unsupported on Windows without the required privilege.

## Recovering an Interrupted Install

An interrupted multi-file install, failed rollback, or failed backup cleanup can
leave `.atmos-onedir.json.bak` in the affected version directory. Atmos preserves
that snapshot and any `.pkg.bak` tree and refuses another install into that
directory. Recovery is intentionally manual: the snapshot alone cannot tell
whether installation stopped before committing or succeeded but could not remove
its backups. Automatically restoring it could replace a successful installation
with the previous version's files.

To recover without discarding either installation:

1. Stop Atmos installs and all processes using this tool, including any shells
   with its directory in `PATH`. On Windows, close processes holding its files
   open before attempting the move.
2. Before moving anything, confirm that the pinned archive is accessible from
   its configured source or cache with the original credentials and verification
   settings. If it is unavailable, leave the installation in place and resolve
   access first. Locate the **version directory** containing the snapshot named in the error:
   `<install_path>/bin/<owner>/<repo>/<version>/`. Move that entire directory,
   including hidden files, to a unique backup location **outside the toolchain
   install directory**. Keep `.pkg`, `.pkg.bak`, both manifest files, and any flat
   executable together. Do not delete just the snapshot or copy its JSON over
   the active manifest; it contains encoded recovery metadata, not a manifest.
3. From the original project and configuration, reinstall the same exact tool
   version, for example `atmos toolchain install nodejs/node@24.18.0 --reinstall`.
   Use the original registry and verification settings. If frozen mode is
   enabled, keep it enabled and retain the original lockfile. Reinstallation
   still depends on the archive remaining available. If it fails, stop all tool
   and install processes again, move any newly created version directory to a
   separate backup, and return the original saved directory to its exact former
   path. Do not merge or overwrite the directories. This restores a previously
   usable committed install; an already interrupted install still needs repair.
4. Check `atmos toolchain which <owner>/<repo>@<version>` and exercise the tool
   before removing the backup. Restart shells that held the old tool path.

If the only message was **"Tool installed, but onedir recovery cleanup needs
attention"**, the new installation has committed and remains usable. Do not
restore the old tree or manifest over it. Use the same backup-and-reinstall
procedure when you can stop the tool to clear the leftover recovery state.

## Try it out

### toolchain

Copy the example into a new directory and make it your own:

```shell
atmos init examples/toolchain
cd toolchain
```

Install the pinned jq binary into this project. Requires network access.

```shell
atmos toolchain install jq
```

- [Installation guide](/install)
- [Explore the example](/examples/toolchain)
- [Initialization and repository settings](/cli/commands/init#examples-and-source-directories)
