A fast, multi-language version manager for macOS
Symlink-based switching · Node.js / Go / Java / Rust / Python · .tool-versions · Auto-switch on cd
Quick Start · Commands · .tool-versions Workflow · FAQ
- Symlink-based switching — version changes take effect instantly, no shim overhead
- Multi-language — manage Node.js, Go, Java (Eclipse Temurin), Rust, and Python from one tool
- Python base + venv integration — managed per-version base environments for global Python CLIs, plus
vex python init/freeze/syncfor project.venvisolation - Python stable latest behavior —
vex list-remote python --filter latestprefers bugfix/security releases over feature or prerelease assets - Shell auto-configuration —
vex init --shell autodetects and configures your shell automatically (zsh, bash, fish, nushell) - Project templates —
vex init --list-templatesandvex init --template <name>bootstrap official starters for Node, Go, Java, Rust, and Python - Safe add-only templating —
vex init --template <name> --add-onlyonly merges.tool-versionsand.gitignore, then creates missing starter files - Fuzzy version matching —
node@20resolves to latest 20.x,node@ltsto latest LTS - Version aliases —
latest,lts,lts-<codename>,stable, minor version matching - Historical Rust stable installs —
vex list-remote rustandvex install rust@1.93.1resolve against Rust's official archived stable installers for the current macOS architecture, not just the current stable release - User-defined aliases —
vex alias set/list/deletefor custom version shortcuts - TUI dashboard —
vex tuifor interactive version overview and health check - Offline mode —
--offlineflag for cache-only operations, no network required - Lockfile support —
vex lockgenerates reproducible.tool-versions.lockwith checksums - Team config sync —
vex install --from/vex sync --fromsupport local files,vex-config.toml, HTTPS team configs, and Git repositories with a safe[tools]schema - Shared npm globals — Shell hooks and
vex exec/runexportNPM_CONFIG_PREFIX=$HOME/.vex/npm/prefixandNPM_CONFIG_USERCONFIG=$HOME/.vex/npm/npmrc, keep~/.vex/npm/prefix/binon PATH, and use that as a shared user-level npm CLI pool across vex-managed Node versions - Global CLI inventory —
vex globalsshows shared npm globals, Python base/user-base CLIs, GoGOBIN, Cargo-installed tools, and Maven/Gradle build-tool state with version-source hints - Auto-export env vars — Automatic
JAVA_HOME,GOROOT,GOENV,CARGO_HOME, captured user-state env vars, Python base/user CLI paths, and project.venvactivation in shell hooks - Official Rust extensions —
vex rust target/componentmanages official Rust toolchain extensions such asrust-srcand iOS std targets - Contained user-state capture — supported language homes, caches, and user bins default into
~/.vex - Explicit home repair —
vex repair migrate-homepreviews and applies safe migrations from legacy home-directory paths - One-command upgrade —
vex upgrade nodeinstalls and switches to the latest version - Managed context upgrades —
vex outdatedinspects the current project/global/active scope, andvex upgrade --allupgrades that whole managed set - Explicit relink for Node toolchain bins —
vex relink noderebuilds~/.vex/binwhen executables appear inside the active Node toolchain - Transient execution —
vex exec -- <command>runs tools in the resolved vex environment without changing global symlinks - Project task runner —
.vex.tomlcan define project env vars and named commands forvex run <task> - Official GitHub Action —
uses: imnotnoahhh/vex@v1installsvexplus cached toolchains and shared npm globals on macOS GitHub Actions runners .tool-versionssupport — per-project pinning, auto-switch oncd, batch install- Project configuration —
.vex.tomladds project-local commands, env vars, behavior overrides, and optional network/mirror overrides - Smart version filtering —
vex list-remote node --filter ltsshows only LTS versions - Remote version cache — cached for 5 min by default, configurable via
config.toml - Concurrent install protection — file-based locking prevents parallel install corruption
- Checksum verification — SHA-256 verification on all 5 tools (Node.js, Go, Java, Rust, Python) before extraction; install refuses to proceed if upstream checksum fetch fails
- Parallel downloads — atomic writes with automatic cleanup, up to 3 concurrent downloads
- Parallel extraction — fast archive extraction using parallel file processing
- Security hardening — TOCTOU protection, ownership validation, path traversal protection, atomic operations
- Self-update —
vex self-updateupgrades vex itself to the latest GitHub release - Health check —
vex doctorvalidates installation, PATH, shell hooks, managed global bins, Maven/Gradle state, and active manager conflicts with actionable fixes - Disk space check — prevents installation when less than 1.5 GB free space available
- Machine-readable output —
--jsonforcurrent,globals,list,list-remote, anddoctor - Homebrew support — optional official tap for brew users, while direct install remains the recommended path
- Multi-shell support — zsh, bash, fish, and nushell integration for auto-switching
- macOS + Linux — supports macOS (Apple Silicon / Intel) and Linux (x86_64 / aarch64); shell hooks work on zsh, bash, fish, nushell
Automatically downloads the correct prebuilt binary for your macOS architecture (arm64/x86_64), installs to ~/.local/bin/vex, and updates your shell PATH configuration:
# Latest release
curl -fsSL https://raw.githubusercontent.com/imnotnoahhh/vex/main/scripts/install-release.sh | bash
# Specific tag
curl -fsSL https://raw.githubusercontent.com/imnotnoahhh/vex/main/scripts/install-release.sh | bash -s -- --version v1.7.0For auditability, review the script before running:
curl -fsSL -o install-release.sh https://raw.githubusercontent.com/imnotnoahhh/vex/main/scripts/install-release.sh
less install-release.sh
bash install-release.sh --helpDownload the prebuilt binary for your architecture from the Releases page:
- Apple Silicon (M1/M2/M3):
vex-aarch64-apple-darwin.tar.gz - Intel:
vex-x86_64-apple-darwin.tar.gz
Extract and install:
tar -xzf vex-*.tar.gz
mkdir -p ~/.local/bin
cp vex-*/vex ~/.local/bin/vex
chmod +x ~/.local/bin/vex
# Add to PATH if not already present
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrcIf you already use Homebrew, vex can also be installed from the official tap:
brew install imnotnoahhh/homebrew-vex/vexDirect installation remains the recommended path because it keeps vex completely independent from Homebrew after setup.
git clone https://github.com/imnotnoahhh/vex.git
cd vex
cargo build --release && cp target/release/vex ~/.local/bin/vexVerify installation:
vex --versionvex init --shell auto
# Or configure shell hooks manually.
# For zsh:
echo 'eval "$(vex env zsh)"' >> ~/.zshrc
source ~/.zshrc
# For bash:
echo 'eval "$(vex env bash)"' >> ~/.bashrc
source ~/.bashrc
# For fish:
echo 'vex env fish | source' >> ~/.config/fish/config.fish
# For nushell:
vex env nu | save -f ~/.config/nushell/vex.nu
echo 'source ~/.config/nushell/vex.nu' >> ~/.config/nushell/config.nuThe generated hook keeps ~/.vex/npm/prefix/bin and ~/.vex/bin on PATH, runs vex use --auto on directory changes, and refreshes the exported activation environment via vex env <shell> --exports. In Node projects, the refreshed PATH prefers the nearest node_modules/.bin before shared npm globals so project-local CLIs win. "Shared" means npm install -g writes to one vex-managed npm CLI pool, not to a separate prefix per Node version.
# Install a specific version (fuzzy matching)
# Note: Automatically switches to the installed version
vex install node@20 # → latest 20.x
vex install node@lts # → latest LTS
vex install node@20.11.0 # → exact version
# Install without switching (preserve current version)
vex install node@20 --no-switch
# Version aliases
vex install node@lts-iron # → specific LTS codename
vex install go@1.23 # → latest 1.23.x
vex install rust@stable # → latest stable
# Bootstrap a project starter
vex init --list-templates
vex init --template node-typescript
vex init --template python-venv --add-only
# Sync from a team-managed source
vex sync --from vex-config.toml
vex sync --from https://company.example/vex-config.toml
vex install --from git@github.com:company/vex-config.git
# Upgrade to latest
vex upgrade node
vex upgrade --all
# Show what is behind latest in the current managed context
vex outdated
# List user-defined aliases
vex alias list
# Run a command in the resolved vex-managed environment
vex exec -- node -v
# Run a named task from .vex.toml
vex run test
# Rebuild Node binary links after toolchain executables change
vex relink node
# Preview or apply safe home-directory migrations into ~/.vex
vex repair migrate-home
vex repair migrate-home --apply
# Manage official Rust extensions for the active toolchain
vex rust target list
vex rust target add aarch64-apple-ios aarch64-apple-ios-sim
vex rust component add rust-src
# Switch versions
vex use node@22
# Pin version for current project
vex local node@20.11.0 # writes .tool-versions
# Install everything from .tool-versions
vex installFor the full CLI reference, including command groups and option details, see docs/guides/command-reference.md.
| Command | Description | Example |
|---|---|---|
vex init |
Initialize directory structure | vex init |
vex init --shell auto |
Initialize and auto-configure shell | vex init --shell auto |
vex init --shell zsh |
Initialize and configure specific shell | vex init --shell zsh |
vex init --list-templates |
List built-in project templates | vex init --list-templates |
vex init --template <name> |
Bootstrap a project starter | vex init --template rust-cli |
vex init --template <name> --add-only |
Safely merge missing template files into an existing repo | vex init --template python-venv --add-only |
vex install <tool@version> |
Install a specific version | vex install node@20 |
vex install <tool@version> <tool@version>... |
Install multiple specific versions | vex install node@20 go@1.24 |
vex install |
Install all from .tool-versions |
vex install |
vex install --from <source> |
Install from a version file, vex-config.toml, HTTPS URL, or Git repo |
vex install --from git@github.com:company/vex-config.git |
vex use <tool@version> |
Switch to installed version | vex use node@22 |
vex use --auto |
Auto-switch from version files | vex use --auto |
vex relink node |
Rebuild ~/.vex/bin from the active Node toolchain |
vex relink node |
vex local <tool@version> |
Pin version in .tool-versions |
vex local node@20.11.0 |
vex global <tool@version> |
Pin version in ~/.vex/tool-versions |
vex global go@1.23 |
vex list <tool> |
List installed versions | vex list node |
vex list <tool> --json |
List installed versions as JSON | vex list node --json |
vex list-remote <tool> |
List all remote versions | vex list-remote node |
vex list-remote <tool> --json |
List remote versions as JSON | vex list-remote node --json |
vex list-remote <tool> -f lts |
List only LTS versions | vex list-remote node -f lts |
vex list-remote <tool> -f major |
List latest of each major version | vex list-remote node -f major |
vex list-remote <tool> --no-cache |
List remote versions (skip cache) | vex list-remote node --no-cache |
vex upgrade <tool> |
Upgrade to latest version | vex upgrade node |
vex upgrade --all |
Upgrade every managed tool in the current context | vex upgrade --all |
vex outdated |
Show managed tools that are behind latest | vex outdated |
vex outdated --json |
Show outdated status as JSON | vex outdated --json |
vex prune --dry-run |
Preview cache, stale-lock, and unused-toolchain cleanup | vex prune --dry-run |
vex gc |
Alias for vex prune |
vex gc --dry-run |
vex install --force |
Reinstall a version even if it already exists | vex install node@20 --force |
vex install --frozen |
Install from version files while strictly enforcing .tool-versions.lock |
vex install --frozen |
vex alias set <tool> <alias> <version> |
Set custom version alias | vex alias set node lts-current 20.11.0 |
vex alias list [tool] |
List all aliases | vex alias list node |
vex alias delete <tool> <alias> |
Delete an alias | vex alias delete node lts-current |
vex lock |
Generate lockfile from .tool-versions |
vex lock |
vex sync --from <source> |
Sync from a version file, vex-config.toml, HTTPS URL, or Git repo |
vex sync --from https://company.example/vex-config.toml |
vex sync --frozen |
Install from lockfile | vex sync --frozen |
vex sync --offline |
Sync using cached metadata and archives only | vex sync --offline |
vex tui |
Launch interactive dashboard | vex tui |
vex install --offline |
Install from cache only | vex install node@20 --offline |
vex exec -- <command> |
Run a command in the resolved vex environment without switching global state | vex exec -- node -v |
vex run <task> [args...] |
Run a named task from .vex.toml |
vex run test -- --nocapture |
vex current |
Show active versions | vex current |
vex current --json |
Show active versions as JSON | vex current --json |
vex globals |
Show global CLIs and Java build-tool state | vex globals --verbose |
vex globals <filter> --json |
Show global CLI inventory for one official tool/ecosystem as JSON | vex globals npm --json |
vex uninstall <tool@version> |
Uninstall a version | vex uninstall node@20.11.0 |
vex doctor |
Run health check and diagnostics | vex doctor |
vex doctor --json |
Run health check and emit JSON | vex doctor --json |
vex doctor --verbose |
Show extra provenance and captured-env details | vex doctor --verbose |
vex repair migrate-home |
Preview or apply safe legacy home-directory migrations into ~/.vex |
vex repair migrate-home --apply |
vex self-update |
Update vex itself to the latest release | vex self-update |
vex env <shell> |
Output shell hook script | vex env zsh |
vex rust target <subcommand> |
Manage official Rust targets for the active Rust toolchain | vex rust target add aarch64-apple-ios |
vex rust component <subcommand> |
Manage official Rust components for the active Rust toolchain | vex rust component add rust-src |
vex python base |
Ensure the active Python base environment exists | vex python base |
vex python base pip <args> |
Run pip inside the active Python base environment | vex python base pip install kaggle |
vex python base freeze |
Lock base Python CLI packages to requirements.lock inside the base env |
vex python base freeze |
vex python base sync |
Restore base Python CLI packages from the base env lockfile | vex python base sync |
vex python init |
Create .venv in current directory |
vex python init |
vex python freeze |
Lock environment to requirements.lock |
vex python freeze |
vex python sync |
Restore environment from requirements.lock |
vex python sync |
| Tool | Binaries | Source | Checksum source |
|---|---|---|---|
| Node.js | node, npm, npx (+ corepack in v24 and earlier) | nodejs.org official binaries | SHASUMS256.txt sidecar |
| Go | go, gofmt | go.dev official binaries | sha256 field in go.dev JSON API |
| Java | java, javac, jar, javadoc + 26 more JDK tools | Eclipse Temurin JDK | Adoptium API binary.package.checksum |
| Rust | rustc, rustdoc, cargo, rustfmt, clippy, rust-analyzer + 5 more | static.rust-lang.org stable channel | .sha256 sidecar in channel manifest |
| Python | python3, pip3, python, pip, 2to3, idle3, pydoc3, python3-config | python-build-standalone (astral-sh) | SHA256SUMS from GitHub release |
- User guides and troubleshooting: docs/README.md
- Full command reference: docs/guides/command-reference.md
- Migration and comparison: docs/guides/migration-comparison.md
- Benchmark methodology: docs/guides/benchmark-methodology.md
- Team and CI recommendations: docs/guides/best-practices.md
- Maintainer and contributor docs: docs/development/README.md
Global settings live in ~/.vex/config.toml. Project settings in .vex.toml can override behavior and network defaults within that repo. Environment variables still take highest precedence for CI and enterprise shells.
# ~/.vex/config.toml
cache_ttl_secs = 300
[network]
connect_timeout_secs = 30
read_timeout_secs = 300
download_retries = 3
proxy = "http://proxy.internal:8080"
[mirrors]
node = "https://mirror.example.com/nodejs"# .vex.toml
[behavior]
auto_switch = true
auto_activate_venv = true
[network]
download_retries = 5
proxy = "http://team-proxy.internal:8080"
[mirrors]
rust = "https://mirror.example.com/rust"
[env]
RUST_LOG = "debug"
[commands]
test = "cargo test"
lint = "cargo clippy --all-targets --all-features -- -D warnings"Use vex exec for one-off commands and vex run for project tasks:
vex exec -- python -m pytest
vex run testFor more detail, see docs/guides/configuration.md.
vex init now has two explicit modes:
vex init --shell ...initializes~/.vexand shell integrationvex init --template ...bootstraps the current project directory
The built-in core templates are:
node-typescriptgo-servicejava-basicrust-clipython-venv
Template defaults:
--dry-runpreviews every file without writing anything- strict mode exits without writing if any target file already exists
--add-onlyonly merges.tool-versionsand.gitignore, then creates any missing starter files
vex install --from and vex sync --from can now consume:
- a local version file such as
.tool-versions - a local
vex-config.toml - an HTTPS-hosted
vex-config.toml - an HTTPS or SSH Git repository whose root contains
vex-config.toml
Team config is intentionally narrow and safe:
version = 1
[tools]
node = "20"
go = "1.24"
python = "3.12"Rules:
- remote team config only supports
[tools] - local
.tool-versionsentries override the remote baseline for matching tools - team config is only loaded when you explicitly pass
--from - local
--fromfile paths are resolved relative to your current working directory
This repository now publishes a macOS-only composite action:
- uses: imnotnoahhh/vex@v1
with:
tools: node@20 go@1.24Or:
- uses: imnotnoahhh/vex@v1
with:
auto-install: trueThe action:
- installs the latest
vexrelease or a requested release tag - caches
~/.vex/cacheand~/.vex/toolchains - re-runs activation after cache restore so
~/.vex/binis ready inPATH
Lock your toolchain versions for reproducible environments:
# 1. Pin versions in .tool-versions
vex local node@20.11.0
vex local go@1.23.5
# 2. Generate lockfile with checksums
vex lock
# Creates .tool-versions.lock with SHA256 checksums
# 3. Commit both files
git add .tool-versions .tool-versions.lock
git commit -m "Lock toolchain versions"Teammates can restore the exact environment:
# Install with frozen lockfile (enforces exact versions)
vex sync --frozenThe lockfile includes SHA256 checksums for security and reproducibility.
Create custom version shortcuts:
# Set a global alias (default)
vex alias set node production 20.11.0
# Set a project-local alias
vex alias set --project node lts-current 20.11.0
# List all aliases
vex alias list node
# Use the alias
vex install node@lts-current
# Delete an alias
vex alias delete node lts-currentAliases are stored in:
- Project:
.vex.toml(committed to git) - Global:
~/.vex/aliases.toml(user-specific)
Project aliases override global aliases.
Version specs don't need to be exact:
vex install node@20 # latest 20.x.x
vex install node@20.11 # latest 20.11.x
vex install node@20.11.0 # exact version
vex install java@21 # exact (Java uses single numbers)| Tool | Aliases |
|---|---|
| Node.js | latest, lts, lts-<codename> (e.g. lts-iron) |
| Go | latest, <major>.<minor> (e.g. 1.23 → latest 1.23.x) |
| Java | latest, lts |
| Rust | latest, stable |
| Python | latest, stable, bugfix, security |
# Inspect remote versions before choosing a built-in alias
vex list-remote node --filter lts# Pin versions for your project
vex local node@20.11.0
vex local go@1.23.5
# .tool-versions is created automatically:
# go 1.23.5
# node 20.11.0
# Teammates clone and run:
vex install # installs everything from .tool-versions
# With shell hook enabled, versions auto-switch on cd
cd my-project # → switches to node 20.11.0, go 1.23.5Python binaries come from python-build-standalone standard install_only CPython packages — prebuilt, standalone binaries with no compilation needed. vex does not currently manage free-threaded Python variants.
# 1. Install a Python version
vex install python@3.12 # or: python@latest, python@bugfix, python@security
# 2. Activate it
vex use python@3.12
# 3. Optional: install global Python CLIs into the managed base env
# These are available when no project .venv is active.
vex python base
vex python base pip install kaggle
kaggle --version
# 4. Create a project venv
# Uses ~/.vex/bin/python3 (the active vex-managed python), falls back to system python3
cd my-project
vex python init # runs: python3 -m venv .venv
# also writes python version to .tool-versions
# 5. Install packages and lock them
pip install requests flask
vex python freeze # runs: pip freeze > requirements.lock
# 6. Commit both files
git add .tool-versions requirements.lockOn a new machine or for a teammate:
vex install python@3.12
cd my-project
vex python sync # auto-creates .venv if missing + pip install -r requirements.lockThe shell hook automatically refreshes PATH, VIRTUAL_ENV, and captured tool env vars when you cd into or out of a project — no manual source .venv/bin/activate needed.
Python has two managed dependency scopes:
~/.vex/python/base/<version>is the per-version base environment. Use it for user-level Python CLIs such askaggle,black, orpipxalternatives when no project.venvis active.project/.venvis the project environment. When the shell hook activates.venv, the Python basebindirectory is intentionally hidden so base packages and CLI scripts do not leak into the project.
If you install a CLI with vex python base pip install kaggle, it is available from the shell outside project virtual environments. Inside a project, install project-specific dependencies into .venv and lock them with vex python freeze.
requirements.lock is generated by pip freeze and pins all packages including transitive dependencies. Commit it to git for reproducible environments.
vex uses symlinks + PATH prepending. No shims, no runtime overhead.
~/.vex/bin/node → ~/.vex/toolchains/node/20.11.0/bin/node
↓ (vex use node@22)
~/.vex/bin/node → ~/.vex/toolchains/node/22.0.0/bin/node
Switching versions just updates symlinks — instant and shell-restart-free.
| vex | nvm | fnm | asdf | mise | |
|---|---|---|---|---|---|
| Multi-language | ✅ | ❌ Node only | ❌ Node only | ✅ | ✅ |
| Python venv management | ✅ built-in | ❌ | ❌ | ❌ | ❌ |
| No shims | ✅ symlinks | ✅ | ✅ | ❌ shims | ❌ shims |
| .tool-versions | ✅ | ❌ | ❌ | ✅ | ✅ |
| Auto-switch on cd | ✅ | ❌ | ✅ | ✅ | ✅ |
| Zero home dir pollution | ✅ all in ~/.vex | ❌ | ❌ | ❌ | ❌ |
| Self-update | ✅ built-in | ❌ | ❌ | ❌ | ❌ |
| Implementation | Rust | Shell | Rust | Shell | Rust |
Why no shims matters: asdf and mise insert a shim binary in front of every command. Every time you run node, the shim wakes up, looks up the version, then execs the real binary. vex skips this entirely — ~/.vex/bin/node is a direct symlink to the real binary. Zero overhead, no startup tax.
Why zero home dir pollution matters: most version managers scatter files across ~/.nvm, ~/.cargo, ~/.cache/node, ~/.tool-versions, etc. vex keeps everything under ~/.vex/ — one directory, easy to back up, easy to nuke.
~/.vex/
├── bin/ # Symlinks (added to PATH)
├── toolchains/ # Installed versions
│ ├── node/
│ │ ├── 20.11.0/
│ │ └── 22.0.0/
│ ├── go/
│ ├── java/
│ └── rust/
├── current/ # Active version symlinks
├── cache/ # Download cache + remote version cache
├── locks/ # Install lock files (concurrent protection)
└── config.toml # Configuration (e.g. cache_ttl_secs)
Run vex doctor to perform a comprehensive health check. It validates:
- vex installation and PATH configuration
- Shell hook setup (auto-switch on cd)
- Installed tool versions and activation status
- Binary symlinks integrity
- Managed Python base environment health and project
.venvisolation - Provides actionable suggestions for fixing issues
Why does vex list-remote go not show every historical Go release?
Go remote listings are constrained by upstream API policy and usually focus on active maintenance lines.
Why does vex list-remote rust show limited choices?
Current Rust support reads channel-rust-stable.toml and only targets the stable channel's current release.
How do I upgrade vex itself?
Run vex self-update. It fetches the latest release from GitHub, downloads the binary for your architecture, and replaces the current executable atomically.
How do I upgrade to the latest version of a tool?
Use vex upgrade <tool>. It installs the latest version and switches to it automatically.
Can it coexist with nvm/fnm? Technically yes, but not recommended — PATH conflicts are likely.
Windows/Linux support? macOS only for now.
How to uninstall vex?
# 1. Remove these lines from ~/.zshrc (or ~/.bashrc):
# eval "$(vex env zsh)"
# export PATH="$HOME/.vex/bin:$PATH"
# 2. Remove vex data and binary
rm -rf ~/.vex
rm -f ~/.local/bin/vexgit clone https://github.com/imnotnoahhh/vex.git
cd vex
cargo build
cargo test
# Optional: run network-dependent tests explicitly
cargo test --features network-tests
# CI-aligned smoke tests
VEX_BIN="$(pwd)/target/debug/vex" bash scripts/test-management-features.sh
VEX_BIN="$(pwd)/target/debug/vex" bash scripts/test-shell-hooks.sh
VEX_BIN="$(pwd)/target/debug/vex" bash scripts/test-rust-extensions-live.shGenerate comprehensive API documentation with custom styling:
# Quick command
make docs
# Or manually
RUSTDOCFLAGS="--html-in-header docs/header.html" cargo doc --no-deps
cp docs/custom.css target/doc/
open target/doc/vex/index.htmlThe documentation includes:
- Pure English documentation for all modules
- Custom theme with improved readability
- Enhanced code highlighting and styling
- Comprehensive module and function documentation
Performance benchmarks are available to measure key operations:
# Run all benchmarks
cargo bench
# Run specific benchmark
cargo bench bench_parse_tool_versions
# Generate detailed reports (saved to target/criterion/)
cargo bench -- --verboseBenchmarked operations:
- Version file parsing (
.tool-versions) - Directory traversal for version resolution
- Symlink creation and updates (version switching)
- Cache read/write operations
- Parallel vs sequential file extraction
Note: Benchmarks are not run in CI to keep build times fast. Run them locally to measure performance improvements.
For reporting guidance and fair comparison rules, see docs/guides/benchmark-methodology.md.
See CONTRIBUTING.md for details.
For usage help, bug reports, and feature requests, see SUPPORT.md. Please report vulnerabilities through SECURITY.md, not public issues.
- Linux support — Extend to Linux distributions (Ubuntu, Debian, Fedora, Arch)
- Windows support — Windows compatibility with junction points
- Plugin system — Allow community-contributed tool adapters
- Version constraints — Support version ranges in
.tool-versions(e.g.,node >=20.0.0 <21.0.0) - Global default versions — Set default versions without
.tool-versionsfile - Parallel installations — Install multiple tools concurrently
- Update notifications — Notify when new tool versions are available
- Self-update — ✅ Done (
vex self-update)
- Additional languages: Ruby, PHP, Elixir, Zig
- Custom binary sources: Support for private registries
- Version pinning strategies: Lock files for reproducible builds
- Integration with CI/CD: GitHub Actions, GitLab CI support
See GitHub Issues for detailed feature requests and discussions.
Thanks to everyone who has contributed to vex!
- Noah Qin - Creator and maintainer
Want to contribute? Check out CONTRIBUTING.md to get started!
MIT © 2026 Noah Qin
