
`varyup` is the Vary toolchain manager. It installs, updates, and switches between Vary compiler releases. Each release is a self-contained archive with the compiler JAR, bundled JRE, standard library, and VS Code extension. `varyup` handles downloading, verifying checksums, and wiring up the `vary` shim so the right version runs when you type `vary`. The design follows [rustup](https://rustup.rs/), adapted for JVM toolchains.

## Quick start

**Linux / macOS:**

```bash
curl -fsSL https://github.com/ccollicutt/vary/releases/latest/download/install.sh | sh
```

**Windows (PowerShell):**

```powershell
irm https://github.com/ccollicutt/vary/releases/latest/download/install.ps1 | iex
```

This downloads varyup, installs the latest Vary toolchain, and sets up the `vary` shim. After running, add `~/.vary/bin` (or `%LOCALAPPDATA%\vary\bin` on Windows) to your PATH, then verify:

```bash
vary --version
```

For platform-specific details see [Linux](/docs/install-linux/), [Windows](/docs/install-windows/), or [macOS](/docs/install-macos/).

## Install varyup

### One-line install (recommended)

The install scripts download the correct varyup binary, install it to `~/.vary/bin/`, and run `varyup toolchain install latest`. See the quick start above.

| Flag | Effect |
|------|--------|
| `--skip-toolchain` (sh) / `-SkipToolchain` (ps1) | Skip automatic toolchain install |

### Manual install

If you prefer not to pipe to a shell, download varyup directly, add it to your PATH, and install a toolchain.

**Linux:**

```bash
mkdir -p ~/.vary/bin
curl -fSL "https://github.com/ccollicutt/vary/releases/latest/download/varyup-linux-x64" -o ~/.vary/bin/varyup
chmod +x ~/.vary/bin/varyup
# Add to ~/.bashrc or ~/.zshrc:
export PATH="$HOME/.vary/bin:$PATH"
varyup toolchain install latest
```

**macOS (Apple Silicon):**

```bash
mkdir -p ~/.vary/bin
curl -fSL "https://github.com/ccollicutt/vary/releases/latest/download/varyup-macos-arm64" -o ~/.vary/bin/varyup
chmod +x ~/.vary/bin/varyup
# Add to ~/.zshrc:
export PATH="$HOME/.vary/bin:$PATH"
varyup toolchain install latest
```

For Intel Macs, use `varyup-macos-x64`.

**Windows (PowerShell):**

```powershell
$varyBin = "$env:LOCALAPPDATA\vary\bin"
mkdir $varyBin -ErrorAction SilentlyContinue
Invoke-WebRequest "https://github.com/ccollicutt/vary/releases/latest/download/varyup-windows-x64.exe" -OutFile "$varyBin\varyup.exe"
# Add to user PATH:
$path = [Environment]::GetEnvironmentVariable("Path", "User")
[Environment]::SetEnvironmentVariable("Path", "$varyBin;$path", "User")
# Open a new terminal, then:
varyup toolchain install latest
```

### Verify

Open a new terminal and run:

```bash
varyup --version
```

## Install a toolchain

See what releases are available:

```bash
varyup toolchain list-available
```

```text
Available toolchains:
  v84-alpha.1 [alpha]
  v83-alpha.1 [alpha]
  v82-alpha.1 [alpha] (installed, default)
  v81-alpha.1 [alpha]
  v79-alpha.1 [alpha] (installed)
```

Installed toolchains are marked. `(default)` shows the active global default.

Install the latest release for your channel, or pick a specific version:

```bash
varyup toolchain install latest
varyup toolchain install v84-alpha.1
```

On first install, varyup downloads the release archive, verifies the SHA256 checksum, extracts it to `~/.varyup/toolchains/`, sets it as the default, and installs the `vary` shim to `~/.vary/bin/`.

After installation, `vary` commands route through the shim to the active toolchain:

```bash
vary --version
vary run hello.vary
```

## Managing toolchains

### List installed toolchains

```bash
varyup toolchain list
```

```text
Installed toolchains:
  v84-alpha.1 (default)
  v82-alpha.1
```

### Switch the default

```bash
varyup default v82-alpha.1
```

### Remove a toolchain

```bash
varyup toolchain uninstall v82-alpha.1
```

You cannot uninstall the active default. Switch to a different default first.

## Release channels

Vary uses six release tracks, from least to most stable:

| Channel | Description |
|---------|-------------|
| `dev` | Automated builds from main, may break |
| `alpha` | Feature-complete snapshots, tested but rough |
| `beta` | API-stable, documents breaking changes |
| `rc` | All gates pass, production evaluation |
| `stable` | Fully validated, recommended for general use |
| `nightly` | Daily builds |

### Set your preferred channel

```bash
varyup toolchain set-channel alpha
```

Check the current channel:

```bash
varyup toolchain get-channel
```

### Install a channel

Channels resolve to the latest matching release:

| Channel | Resolves to |
|---------|-------------|
| `stable` | Latest non-prerelease GitHub release |
| `nightly` | Latest release with "nightly" in the tag |
| `nightly-YYYY-MM-DD` | Specific nightly release by date |

```bash
varyup toolchain install stable
```

### Update channels

Update all channels to their latest versions:

```bash
varyup toolchain update --all
```

Or update a specific channel:

```bash
varyup toolchain update stable
```

Pinned versions (e.g. `v82-alpha.1`) are not affected by update.

## Per-project toolchain selection

### Option 1: `vary-toolchain.toml`

Create a `vary-toolchain.toml` in your project root:

```toml
toolchain = "v1alpha1"
```

When you run `vary` from that directory (or any subdirectory), varyup uses the specified toolchain. This file should be committed to version control so all contributors use the same version.

### Option 2: Directory overrides

Overrides pin a directory tree to a toolchain on your machine, without adding a file to the project. This is stored in your personal `~/.varyup/settings.toml`, not in the project, so it won't affect other contributors.

Set an override for the current directory:

```bash
cd ~/projects/legacy-app
varyup override set v82-alpha.1
```

Now any `vary` command run from `~/projects/legacy-app` (or any subdirectory) uses `v82-alpha.1`, even if your global default is something newer. The resolver walks from CWD upward to the filesystem root and uses the first matching override.

List all overrides:

```bash
varyup override list
```

```text
Directory overrides:
  /home/user/projects/legacy-app → v82-alpha.1
  /home/user/projects/experiment → nightly
```

Remove the override for the current directory:

```bash
cd ~/projects/legacy-app
varyup override unset
```

This only removes the exact directory entry. Parent overrides are not affected.

### Which option to use?

| | `vary-toolchain.toml` | `override set` |
|---|---|---|
| Stored in | Project directory (commit to git) | `~/.varyup/settings.toml` (personal) |
| Affects | Everyone who clones the project | Only you |
| Use when | The project requires a specific version | You personally want a different version here |

### Resolution precedence

When you run `vary`, varyup resolves the toolchain in this order:

| Priority | Source | Example |
|----------|--------|---------|
| 1 | `VARYUP_TOOLCHAIN` environment variable | `VARYUP_TOOLCHAIN=nightly vary run app.vary` |
| 2 | Directory override | `varyup override set nightly` |
| 3 | `vary-toolchain.toml` (walks up to root) | `toolchain = "v1alpha1"` |
| 4 | Global default | `varyup default v1alpha1` |
| 5 | Error | No toolchain configured |

## VS Code extension

Each toolchain bundles the Vary VS Code extension (`.vsix`). Install it from the active toolchain:

```bash
varyup vscode install
```

This finds the `.vsix` in the active toolchain and runs `code --install-extension`. If `code` is not on your PATH, it prints the path so you can install manually.

To get the `.vsix` path for scripting:

```bash
varyup which vsix
```

See [VS Code](/docs/vscode/) for full extension documentation.

## Self-update

Update varyup itself:

```bash
varyup self update
```

This downloads the latest varyup release, verifies it, and replaces the running binary. The `vary` shim is also updated.

## Uninstall

To remove everything (varyup, all toolchains, and configuration):

### Linux / macOS

```bash
rm -rf ~/.varyup ~/.vary
```

Then remove the PATH line from your shell profile (`~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish`):

```bash
export PATH="$HOME/.vary/bin:$PATH"   # delete this line
```

### Windows

```powershell
Remove-Item -Recurse -Force "$env:LOCALAPPDATA\varyup", "$env:LOCALAPPDATA\vary"
```

Then remove `%LOCALAPPDATA%\vary\bin` from your user PATH:

```powershell
$varyBin = "$env:LOCALAPPDATA\vary\bin"
$path = [Environment]::GetEnvironmentVariable("Path", "User")
$newPath = ($path -split ";" | Where-Object { $_ -ne $varyBin }) -join ";"
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
```

This removes varyup, all installed toolchains, the `vary` shim, configuration, channel pointers, and the download cache. Nothing is left on disk.

To remove a single toolchain without uninstalling varyup, use `varyup toolchain uninstall <version>`.

## Diagnostics

Show the current configuration and troubleshooting information:

```bash
varyup show
```

Output:

```text
varyup v0.1.0 (abc1234) 2026-02-24T00:00:00Z

VARYUP_HOME: /home/user/.varyup
VARY_HOME:   /home/user/.vary

Channel:           alpha
Default toolchain: v82-alpha.1
Active toolchain:  v82-alpha.1 (via default)
Binary path:       /home/user/.varyup/toolchains/v82-alpha.1/bin/vary
```

Find the path to the active `vary` binary:

```bash
varyup which vary
```

For detailed diagnostics (platform, environment variables, installed toolchains):

```bash
varyup diagnostics
```

## Filesystem layout

varyup uses two directories:

### `~/.varyup` (toolchain home)

Override with `VARYUP_HOME`. On Windows this defaults to `%LOCALAPPDATA%\varyup`.

```text
~/.varyup/
  settings.toml          # Default toolchain, overrides, repo config
  toolchains/
    v1alpha1/            # Installed toolchain
    nightly-2026-02-24/
  channels/
    stable.toml          # Channel pointer: resolved_tag, installed_at
    nightly.toml
  downloads/             # Download cache
  tmp/                   # Temporary extraction directory
  locks/                 # File locks for concurrent safety
```

### `~/.vary/bin` (user-facing binaries)

Override with `VARY_HOME`. This directory must be on your PATH. On Windows this defaults to `%LOCALAPPDATA%\vary\bin`.

```text
~/.vary/bin/
  varyup                 # Toolchain manager
  vary                   # Shim (same binary, dispatches via argv0)
```

## Configuration

Global settings are stored in `~/.varyup/settings.toml`. On first run, varyup creates this file with annotated defaults.

```toml
# Preferred release channel
channel = "alpha"

# Default toolchain (set with: varyup default <spec>)
default_toolchain = "v82-alpha.1"

# GitHub repository for Vary releases
github_repo = "ccollicutt/vary"

# GitHub repository for varyup self-update releases
varyup_repo = "ccollicutt/vary"

# Include draft (unpublished) releases (requires push access)
# include_drafts = false

# Directory overrides
[overrides]
"/home/user/project-a" = "nightly"
"/home/user/project-b" = "v82-alpha.1"
```

| Field | Default | Description |
|-------|---------|-------------|
| `channel` | `alpha` | Preferred release channel (dev, alpha, beta, rc, stable, nightly) |
| `default_toolchain` | (none) | Global default toolchain |
| `github_repo` | `ccollicutt/vary` | Repository for Vary releases |
| `varyup_repo` | `ccollicutt/vary` | Repository for varyup releases |
| `include_drafts` | `false` | Include draft releases (requires push access to the repo) |
| `[overrides]` | (none) | Directory-to-toolchain mappings |

### Environment variable overrides

Every config field can be overridden with an environment variable. Env vars take precedence over the config file.

| Variable | Overrides |
|----------|-----------|
| `VARYUP_CHANNEL` | `channel` |
| `VARYUP_DEFAULT_TOOLCHAIN` | `default_toolchain` |
| `VARYUP_GITHUB_REPO` | `github_repo` |
| `VARYUP_REPO` | `varyup_repo` |
| `VARYUP_INCLUDE_DRAFTS` | `include_drafts` (set to `1`/`true` or `0`/`false`) |

## Command reference

Every command has a short alias. The alias is shown in parentheses.

| Command | Alias | Description |
|---------|-------|-------------|
| `varyup toolchain` | `tc` | Manage toolchains |
| `varyup toolchain install <spec>` | `tc i` | Install a toolchain (`latest`, `stable`, `v84-alpha.1`, ...) |
| `varyup toolchain uninstall <spec>` | `tc rm` | Remove a toolchain |
| `varyup toolchain list` | `tc ls` | List installed toolchains |
| `varyup toolchain list-available` | `tc la` | List releases available from GitHub |
| `varyup toolchain list-available --filter <track>` | | Filter by release track |
| `varyup toolchain channels` | `tc ch` | Show channels and their latest versions |
| `varyup toolchain set-channel <track>` | | Set the preferred release channel |
| `varyup toolchain get-channel` | | Show the current release channel |
| `varyup toolchain update [spec]` | `tc up` | Update a channel toolchain |
| `varyup toolchain update --all` | | Update all channels |
| `varyup default <spec>` | `use`, `def` | Set the global default |
| `varyup override set <spec>` | `ov set` | Set a directory override |
| `varyup override unset` | `ov unset` | Remove the current directory's override |
| `varyup override list` | `ov list` | List all overrides |
| `varyup show` | | Show active toolchain and config |
| `varyup which vary` | | Print the resolved binary path |
| `varyup which vsix` | | Print the path to the VS Code extension |
| `varyup vscode install` | `code install` | Install the VS Code extension from the active toolchain |
| `varyup diagnostics` | `diag` | Show troubleshooting info |
| `varyup self update` | | Update varyup itself |
| `varyup completions <shell>` | | Generate shell completions (bash, zsh, fish, powershell) |

## Next steps

| Action | Link |
|--------|------|
| Write your first program | [Getting Started](/docs/getting-started/) |
| Install the VS Code extension | [VS Code](/docs/vscode/) |
| Learn the CLI | [CLI Reference](/docs/cli/) |
