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
- Clone the repository or download the pre-built binary for your platform.
- If downloading the source code, build and install the program:
go install
Or use the justfile if available:
just install
Note: using
go installdoes not add build metadata like version information. To include that, use the justfile or build with ldflags. See details in "Build-time Configuration" section.
- 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 versionsmigrate: Migrate from a system-wide installation to user-local installationcleanup: Interactively clean up old Zig versionsversion: Show version information about the installerenv: 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:
- 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) - Moves them to
~/.local/share/zig/(preserving all versions - no redownload needed!) - Migrates ZLS from
/opt/zlsor/usr/local/zlsto~/.local/share/zls/ - Recreates symlinks in
~/.local/bin/pointing to your previously active version - Cleans up old symlinks from
/usr/local/bin/ - Ready immediately - no reinstallation required
Option 1: Use the Migrate Command (Recommended)
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 versionto verify it works - Run
zig-installer switchto 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/zlsor/usr/local/zls - Moved to:
~/.local/share/zls/
Symlinks:
- Old:
/usr/local/bin/zigand/usr/local/bin/zls - New:
~/.local/bin/zigand~/.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
Alternative: Clean Install (Not Recommended)
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
switchcommand 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 versionto 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):
- Command-line flags: Options provided directly when running the program
- Configuration file: Settings in an
.envfile
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:
- Use the
envcommand to create a template:./zig-installer env - Use the
--generate-envflag 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:
- The upstream Zig project rotates their signing keys and the hardcoded default is outdated
- 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:
- Scan for all installed Zig versions in
~/.local/share/zig/ - Display a table showing version, size, install date, and current status
- Allow you to select which versions to remove (the current version cannot be removed)
- Ask for confirmation before removing
- 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-onlywith--version, only Zig will be installed at the specified version - When using
--zls-onlywith--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:
- No sudo required: Safer and more convenient - no risk of accidentally damaging system files
- Per-user versions: Each user can have their own Zig versions without conflicts
- Standard practice: Follows the same pattern as rustup, nvm, pyenv, and other modern language installers
- Easier cleanup: No permission issues when removing old versions
- 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/binshould come before/usr/local/binin 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:
- Zig versions are MOVED (not deleted): All versions in
/opt/zigare moved to~/.local/share/zig/ - ZLS is MOVED (not deleted): The ZLS installation in
/opt/zlsis moved to~/.local/share/zls/ - Symlinks are recreated: Your previously active version remains active after migration
- 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/binis 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}tozig-installer
New Features:
- Added
migratecommand 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
¶
There is no documentation for this package.