zig-installer

command module
v1.0.1-0...-c8f0c1c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 1 Imported by: 0

README

Zig and ZLS Installer

BREAKING CHANGE - v4.0.0: This installer now uses user-local installation only (no more sudo required). If you have an existing system-wide installation, see the Migration Guide below.

This program installs Zig and the Zig Language Server (ZLS) to your local user directory. You can choose to install both or just one of them.

Platform Support:

  • Linux: Fully supported
  • macOS: Experimental support (ARM64 and x86_64)

Important: Do NOT run this installer with sudo. It installs to your home directory and does not require root privileges.

Installation Directories

The installer uses the following user-local directories:

  • Zig installations: ~/.local/share/zig/
  • ZLS installations: ~/.local/share/zls/
  • Symlinks (zig, zls): ~/.local/bin/

No system-wide directories (/opt, /usr/local) are used.

Prerequisites

Before running the program, ensure you have the following dependencies installed:

  • wget (for downloading Zig binary)
  • git (for downloading ZLS)
  • minisign (for verifying Zig download)
  • xz (for extracting archives)

Installation

  1. Clone the repository or download the pre-built binary for your platform.
  2. If downloading the source code, build and install the program:
go install

Or use the justfile if available:

just install

Note: using go install does not add build metadata like version information. To include that, use the justfile or build with ldflags. See details in "Build-time Configuration" section.

  1. Run the program with the desired options (no sudo required).

Usage

./zig-installer [command] [OPTIONS]
Commands
  • install: Install Zig and/or ZLS (default if no command specified)
  • switch: Switch between installed Zig versions
  • migrate: Migrate from a system-wide installation to user-local installation
  • cleanup: Interactively clean up old Zig versions
  • version: Show version information about the installer
  • env: Generate a template .env file
Options
Installation Options
  • --zig-only: Install only Zig
  • --zls-only: Install only ZLS (Zig Language Server)
  • --version, -v <version>: Specify Zig version to install (default: latest master)
Cleanup Options
  • --auto-cleanup: Automatically cleanup old versions after install without prompting
  • --no-cleanup: Disable auto-cleanup prompt after install
  • --keep-last <N>: Keep last N versions when cleaning up
Output Control
  • --verbose: Show detailed output during installation
  • --no-color: Disable colored output
Configuration
  • --env <file>: Specify a custom environment file (default: .env)
  • --settings: Show current configuration settings
Logging
  • --log-file <file>: Specify log file (default: zig-install.log)
  • --enable-log: Enable/disable logging to file (enabled by default)

Migrating from System Installation

If you previously used an older version of this installer that installed Zig to /opt/zig or /usr/local/zig, the migrate command will preserve your installations by moving them to ~/.local/share/.

Migration Overview

The migrate command:

  1. Discovers all Zig versions in system directories (e.g., /opt/zig/zig-linux-x86_64-0.13.0, /opt/zig/zig-linux-x86_64-0.12.0)
  2. Moves them to ~/.local/share/zig/ (preserving all versions - no redownload needed!)
  3. Migrates ZLS from /opt/zls or /usr/local/zls to ~/.local/share/zls/
  4. Recreates symlinks in ~/.local/bin/ pointing to your previously active version
  5. Cleans up old symlinks from /usr/local/bin/
  6. Ready immediately - no reinstallation required

Dry run first (recommended):

./zig-installer migrate --dry-run

This shows what would be migrated without making changes. Example output:

==> Discovering installations
  --> Success: Found 3 Zig version(s)
  --> Success: Found ZLS installation: /opt/zls
  --> Active version: 0.13.0

[Dry Run] Would migrate 3 Zig versions:
  - 0.13.0 (127 MB) -> ~/.local/share/zig/
  - 0.12.0 (115 MB) -> ~/.local/share/zig/
  - 0.11.0 (98 MB) -> ~/.local/share/zig/

[Dry Run] Would migrate ZLS -> ~/.local/share/zls/

[Dry Run] Would recreate symlinks:
  - ~/.local/bin/zig -> zig-linux-x86_64-0.13.0/zig
  - ~/.local/bin/zls -> zls/zig-out/bin/zls

[Dry Run] Would remove system symlinks:
  - /usr/local/bin/zig
  - /usr/local/bin/zls

Run the actual migration:

./zig-installer migrate

This will:

  • Prompt for your sudo password (needed to move files from /opt/)
  • Move all discovered installations to ~/.local/share/
  • Set up symlinks so everything works immediately
  • Your Zig and ZLS commands will continue working without interruption

After migration:

  • All your existing versions are preserved in ~/.local/share/zig/
  • No need to reinstall or redownload anything
  • Run zig version to verify it works
  • Run zig-installer switch to switch between migrated versions
Option 2: Automatic Migration During Install

When you run install, the installer will detect any existing system installation and offer migration:

./zig-installer install

You'll see:

⚠ Found existing system-wide installation
? How would you like to proceed?
  > Migrate to user-local (move existing installations) [Recommended]
    Keep both (may cause PATH conflicts)
    Cancel installation
  • Migrate: Moves system installations to user-local (preserves your existing versions)
  • Keep both: Installs user-local version alongside system version (you'll get PATH warnings)
  • Cancel: Exits without making changes
Understanding What Gets Migrated

Zig versions:

  • All zig-* directories in /opt/zig/ or /usr/local/zig/
  • Example: zig-linux-x86_64-0.13.0, zig-linux-x86_64-0.12.0
  • Moved to: ~/.local/share/zig/

ZLS installation:

  • Directory /opt/zls or /usr/local/zls
  • Moved to: ~/.local/share/zls/

Symlinks:

  • Old: /usr/local/bin/zig and /usr/local/bin/zls
  • New: ~/.local/bin/zig and ~/.local/bin/zls
  • The new symlinks point to the same version you were using before

What if a version already exists? If you've already installed a version to ~/.local/share/zig/, the migration will skip it and keep your user-local version. This prevents conflicts and prefers your existing installations.

Manual Migration

If you prefer to manually move the system installation (or if automatic migration fails):

Linux:

# Create destination directories
mkdir -p ~/.local/share/zig ~/.local/share/zls ~/.local/bin

# Move Zig versions (preserves all installed versions)
sudo mv /opt/zig/zig-* ~/.local/share/zig/

# Move ZLS (if exists)
sudo mv /opt/zls ~/.local/share/zls/

# Fix ownership
sudo chown -R $USER:$USER ~/.local/share/zig ~/.local/share/zls

# Create symlinks (adjust version as needed)
ln -s ~/.local/share/zig/zig-linux-x86_64-0.13.0/zig ~/.local/bin/zig
ln -s ~/.local/share/zls/zig-out/bin/zls ~/.local/bin/zls

# Clean up old system symlinks
sudo rm -f /usr/local/bin/zig /usr/local/bin/zls

# Remove empty directories
sudo rmdir /opt/zig /opt/zls 2>/dev/null || true

Verify the migration:

which zig  # Should show: /home/yourusername/.local/bin/zig
zig version
zls --version

If you don't want to preserve your existing installations, you can remove them and reinstall:

Linux:

sudo rm -rf /opt/zig /opt/zls
sudo rm -f /usr/local/bin/zig /usr/local/bin/zls

macOS:

sudo rm -rf /usr/local/zig /usr/local/zls /opt/zig /opt/zls
sudo rm -f /usr/local/bin/zig /usr/local/bin/zls

Then install fresh:

./zig-installer install

Note: This approach requires redownloading everything, which wastes bandwidth and time. The migrate command is recommended instead.

PATH Configuration

After installation, ensure ~/.local/bin is in your PATH. The installer will check this automatically and provide instructions if needed.

Bash / Zsh

Add to ~/.bashrc or ~/.zshrc:

export PATH="$HOME/.local/bin:$PATH"

Then reload your shell:

source ~/.bashrc  # or source ~/.zshrc
Fish

Add to ~/.config/fish/config.fish:

set -gx PATH $HOME/.local/bin $PATH

Then reload:

source ~/.config/fish/config.fish
Verify PATH

Check that zig is available:

which zig
# Should output: /home/yourusername/.local/bin/zig

zig version

Switching Between Versions

If you have multiple Zig versions installed, you can quickly switch between them using the switch command. This updates the symlink in ~/.local/bin/zig to point to a different installed version.

Interactive Selection

Run the switch command without arguments to see a list of installed versions:

zig-installer switch

This will display an interactive menu where you can select the version you want to use. The currently active version is marked with an arrow (→).

Direct Version Switch

You can also switch to a specific version directly:

# Using positional argument
zig-installer switch 0.13.0

# Using flag
zig-installer switch --version 0.13.0
Requirements
  • Multiple Zig versions must be installed (use zig-installer install <version> to install more)
  • Only works with user-local installations in ~/.local
Notes
  • The switch command only affects the Zig binary, not ZLS
  • ZLS versions are typically tied to specific Zig versions
  • If you need a different ZLS version, reinstall it with: zig-installer install --zls-only
  • After switching, verify with zig version to confirm the change
Example Workflow
# Install multiple versions
zig-installer install 0.13.0
zig-installer install 0.12.0

# Switch between them
zig-installer switch 0.12.0
zig version  # Shows 0.12.0

zig-installer switch 0.13.0
zig version  # Shows 0.13.0

# Or use interactive selection
zig-installer switch
# → 0.13.0 (current)
#   0.12.0

Configuration

This program can be configured in two ways (in order of precedence):

  1. Command-line flags: Options provided directly when running the program
  2. Configuration file: Settings in an .env file

Before running the program, it will check for required dependencies like wget, git, minisign, and xz. If any are missing, it will inform you so you can install them.

Configuration File (.env)

You can create a .env file in the same directory as the executable in two ways:

  1. Use the env command to create a template:
    ./zig-installer env
    
  2. Use the --generate-env flag with the install command:
    ./zig-installer install --generate-env
    

You can view your current configuration settings at any time using the --settings flag:

./zig-installer install --settings
# Zig download and verification
ZIG_PUB_KEY=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
ZIG_DOWN_URL=https://ziglang.org/builds/
ZIG_INDEX_URL=https://ziglang.org/download/index.json

The values override the defaults.

Creating a .env file is optional, but it allows for easy customization without modifying the source code. It allows you to update settings in the event of:

  1. The upstream Zig project rotates their signing keys and the hardcoded default is outdated
  2. The upstream Zig project has moved to a new download URL
Build-time Configuration (Linker Flags)

When building from source, you can also customize some defaults using linker flags:

go build -ldflags="-X 'github.com/exilesprx/zig-installer/internal/config.Version=VERSION' 'github.com/exilesprx/zig-installer/internal/config.Commit=COMMIT' 'github.com/exilesprx/zig-installer/internal/config.BuildDate=DATE'"

The justfile in this project automatically sets the ldflags during build and is the recommended way to build.

Examples

Basic Installation

Install both Zig and ZLS (latest master):

./zig-installer install

Install only Zig:

./zig-installer install --zig-only

Install only ZLS (Zig Language Server): Note: You must have Zig installed in order to compile ZLS.

./zig-installer install --zls-only
Version-Specific Installation

Install a specific version (both Zig and ZLS will be installed at this version):

./zig-installer install --version 0.11.0

Install only Zig at a specific version:

./zig-installer install --zig-only --version 0.11.0

Install only ZLS (will use current Zig version regardless of --version):

./zig-installer install --zls-only --version 0.11.0  # Note: version will be ignored
Installation with Options

Install with verbose output and custom log file:

./zig-installer install --verbose --log-file custom.log

Install a specific version with auto-cleanup (keep last 2 versions):

./zig-installer install --version 0.13.0 --auto-cleanup --keep-last 2

Install without cleanup prompt:

./zig-installer install --version 0.13.0 --no-cleanup
Cleanup Commands

Cleanup old versions interactively:

./zig-installer cleanup

Cleanup keeping last 3 versions:

./zig-installer cleanup --keep-last 3 --yes

Dry run to see what would be removed:

./zig-installer cleanup --dry-run
Other Commands

Display the current settings:

./zig-installer install --settings

Generate a template .env file:

./zig-installer env

Show version information:

./zig-installer version

Migrate from system installation:

./zig-installer migrate

Cleanup Old Versions

The installer provides powerful tools to manage disk space by removing old Zig versions.

Manual Cleanup

Run the cleanup command to interactively select versions to remove:

./zig-installer cleanup

This will:

  1. Scan for all installed Zig versions in ~/.local/share/zig/
  2. Display a table showing version, size, install date, and current status
  3. Allow you to select which versions to remove (the current version cannot be removed)
  4. Ask for confirmation before removing
  5. Show how much disk space was freed

Note: The cleanup command only manages user-local installations (~/.local/share/zig/). If you have a system installation in /opt/zig or /usr/local/zig, the cleanup command will warn you and provide instructions for manual removal.

Cleanup Command Options

Interactive Mode (Default)

# Select versions manually from an interactive list
./zig-installer cleanup

Dry Run Mode

# See what would be removed without actually removing anything
./zig-installer cleanup --dry-run

Auto-Cleanup with Keep-Last

# Keep the last 3 versions, automatically remove older ones
./zig-installer cleanup --keep-last 3

# Skip confirmation prompt with --yes flag
./zig-installer cleanup --keep-last 3 --yes
Auto-Cleanup After Install

By default, when you install a specific Zig version, the installer will automatically prompt you to clean up old versions after a successful installation.

# Install Zig 0.13.0 - will prompt for cleanup after install
./zig-installer install --version 0.13.0

# After successful installation, you'll see:
# ℹ Found 3 other installed versions (308 MB)
# ? Clean up old versions? [Y/n]:
Controlling Auto-Cleanup Behavior

Disable Auto-Cleanup Prompt

# Install without cleanup prompt (opt-out)
./zig-installer install --version 0.13.0 --no-cleanup

Auto-Cleanup Without Prompting

# Install and automatically show cleanup selection UI
./zig-installer install --version 0.13.0 --auto-cleanup

# Install and automatically keep last 2 versions
./zig-installer install --version 0.13.0 --auto-cleanup --keep-last 2
Cleanup Examples

Example 1: Interactive Cleanup

$ ./zig-installer cleanup

==> Scanning for installed Zig versions...
  --> Success: Found 4 installed versions

┌─────────────────────────┬─────────┬──────────────┬─────────┐
│ Version                 │ Size    │ Install Date │ Current │
├─────────────────────────┼─────────┼──────────────┼─────────┤
│ 0.13.0                  │ 127 MB  │ 2024-01-15   │    ✓    │
│ 0.12.0                  │ 115 MB  │ 2023-11-10   │         │
│ 0.11.0                  │ 98 MB   │ 2023-08-05   │         │
│ 0.10.1                  │ 95 MB   │ 2023-05-20   │         │
└─────────────────────────┴─────────┴──────────────┴─────────┘

Total disk usage: 435 MB

? Select versions to remove (space to select, enter to confirm):
  [x] 0.12.0
  [ ] 0.11.0
  [x] 0.10.1

==> Removing versions...
  --> Success: Removed 0.12.0 (115 MB)
  --> Success: Removed 0.10.1 (95 MB)

✓ Cleanup completed successfully!
✓ Freed 210 MB of disk space

Example 2: Auto-Cleanup After Install

$ ./zig-installer install --version 0.13.0

==> Zig Installation
  --> Success: Zig 0.13.0 installed and configured

ℹ Found 3 other installed versions (308 MB)

? Clean up old versions? [Y/n]: y

[Interactive selection UI shown...]

==> Removing 2 versions...
  --> Success: Removed 0.12.0
  --> Success: Removed 0.10.1

✓ Freed 210 MB of disk space

Example 3: Keep Last N Versions

$ ./zig-installer cleanup --keep-last 2 --yes

==> Auto-cleanup mode (keeping last 2 versions)

Keeping: 0.13.0, 0.12.0
Removing: 0.11.0, 0.10.1

==> Removing versions...
  --> Success: Removed 0.11.0 (98 MB)
  --> Success: Removed 0.10.1 (95 MB)

✓ Cleanup completed successfully!
✓ Freed 193 MB of disk space

Version Management

The installer manages Zig and ZLS versions in the following way:

  • When using --version, both Zig and ZLS will be installed at the specified version to ensure compatibility
  • When using --zig-only with --version, only Zig will be installed at the specified version
  • When using --zls-only with --version, ZLS will be installed matching your current Zig version, ignoring the specified version
  • If no version is specified, the latest master versions will be used

This versioning strategy ensures that Zig and ZLS remain compatible with each other.

Frequently Asked Questions

Why did the installer change to user-local only?

User-local installation provides several benefits:

  1. No sudo required: Safer and more convenient - no risk of accidentally damaging system files
  2. Per-user versions: Each user can have their own Zig versions without conflicts
  3. Standard practice: Follows the same pattern as rustup, nvm, pyenv, and other modern language installers
  4. Easier cleanup: No permission issues when removing old versions
  5. Better isolation: Development tools shouldn't require system-wide installation
What if I run the installer with sudo?

The installer will reject sudo and display an error message:

✗ Error: This installer should NOT be run with sudo

As of v4.0.0, zig-installer uses user-local installation only.
It installs to ~/.local/share/zig and does not require root privileges.

If you have an existing system-wide installation, please run:
  zig-installer migrate
Can I still use my old system installation?

Yes, but it's not recommended. If you keep both:

  • PATH priority matters: ~/.local/bin should come before /usr/local/bin in your PATH
  • Confusion risk: Having multiple installations can lead to using the wrong version
  • No cleanup support: The installer's cleanup command won't manage system installations

The installer will warn you about PATH conflicts if you choose to keep both.

How do I uninstall completely?

Remove user-local installation:

rm -rf ~/.local/share/zig ~/.local/share/zls
rm -f ~/.local/bin/zig ~/.local/bin/zls

Remove system installation (if you have one):

sudo rm -rf /opt/zig /opt/zls /usr/local/zig /usr/local/zls
sudo rm -f /usr/local/bin/zig /usr/local/bin/zls
Does this work on macOS?

Yes, but macOS support is experimental. The installer will display a warning on macOS:

⚠ Warning: macOS support is experimental
  Please report any issues at: https://github.com/exilesprx/zig-installer/issues

Both ARM64 (Apple Silicon) and x86_64 (Intel) are supported.

What if ~/.local/bin is not in my PATH?

After installation, the installer automatically checks your PATH. If ~/.local/bin is not found, it will show shell-specific instructions:

For Bash/Zsh:

export PATH="$HOME/.local/bin:$PATH"

For Fish:

set -gx PATH $HOME/.local/bin $PATH

You'll need to add this to your shell's config file and reload.

Can I install to a custom directory?

Not currently. The installer uses ~/.local/share/zig and ~/.local/share/zls following the XDG Base Directory specification. This is a standard location for user-specific data files.

What happens to my old versions after migration?

When you run zig-installer migrate:

  1. Zig versions are MOVED (not deleted): All versions in /opt/zig are moved to ~/.local/share/zig/
  2. ZLS is MOVED (not deleted): The ZLS installation in /opt/zls is moved to ~/.local/share/zls/
  3. Symlinks are recreated: Your previously active version remains active after migration
  4. No redownload needed: Everything works immediately without reinstallation

Example:

  • Before: /opt/zig/zig-linux-x86_64-0.13.0 (127 MB)
  • After: ~/.local/share/zig/zig-linux-x86_64-0.13.0 (same 127 MB, moved)

Use --dry-run to preview what will be migrated before making changes:

./zig-installer migrate --dry-run
How do I check which installation I'm using?
which zig
# User-local: /home/yourusername/.local/bin/zig
# System-wide: /usr/local/bin/zig

zig version

If which zig shows /usr/local/bin/zig, you're still using a system installation.

Notes

  • This installer uses user-local directories only - no system-wide installation
  • Do NOT run with sudo - the installer will reject it
  • Configuration via .env file allows for easy customization without rebuilding
  • Logging is enabled by default to zig-install.log, but can be configured or disabled
  • The program performs automatic dependency checks before installation
  • The program automatically checks if ~/.local/bin is in your PATH
  • Auto-cleanup is enabled by default when installing specific versions (can be disabled with --no-cleanup)
  • The cleanup command protects the currently active version from accidental removal
  • Multiple Zig versions can be installed side-by-side in ~/.local/share/zig/
  • The cleanup command only manages user-local installations

Changelog

v4.0.0 - Breaking Changes

Major Changes:

  • BREAKING: Removed system-wide installation support - user-local only (~/.local/)
  • BREAKING: Installer now rejects sudo - no root privileges required or allowed
  • BREAKING: Binary renamed from zig-install-{platform} to zig-installer

New Features:

  • Added migrate command to migrate from system installations
  • Automatic detection of existing system installations with migration prompt
  • PATH configuration detection with shell-specific instructions
  • Warning when system installation exists alongside user-local installation

Installation Directories Changed:

  • Old: /opt/zig (Linux), /usr/local/zig (macOS)
  • New: ~/.local/share/zig (all platforms)
  • Old: /opt/zls (Linux), /usr/local/zls (macOS)
  • New: ~/.local/share/zls (all platforms)
  • Old: /usr/local/bin/zig (symlink)
  • New: ~/.local/bin/zig (symlink)

Cleanup Command Changes:

  • Cleanup now only manages ~/.local/share/zig/ versions
  • Cleanup warns if system installation detected
  • No longer requires sudo

Migration Path: Run zig-installer migrate to remove system installations, or use the automatic migration prompt during install.

Troubleshooting

Migration fails with "permission denied"

If zig-installer migrate fails with permission errors, you may need to manually remove the system installation:

Linux:

sudo rm -rf /opt/zig /opt/zls /usr/local/bin/zig /usr/local/bin/zls

macOS:

sudo rm -rf /usr/local/zig /usr/local/zls /opt/zig /opt/zls /usr/local/bin/zig /usr/local/bin/zls

After manual cleanup, you can verify with:

ls -la /usr/local/bin/zig  # Should show "No such file or directory"
ls -la /opt/zig            # Should show "No such file or directory"

Then install the user-local version:

./zig-installer install
"command not found" after migration

If you get "zig: command not found" after migration, ensure ~/.local/bin is in your PATH. See the PATH Configuration section above.

Multiple zig versions found

If which -a zig shows multiple zig installations:

$ which -a zig
/home/user/.local/bin/zig       # User-local (preferred)
/usr/local/bin/zig              # System-wide (old)

The first one in your PATH will be used. To remove the system installation, see "Migration fails with permission denied" above.

License

This project is licensed under the MIT License.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package cmd defines the root command and shared functionality for the zig-installer CLI application.
Package cmd defines the root command and shared functionality for the zig-installer CLI application.
internal
tui

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL