Core Concepts
Understanding the core concepts behind vx helps you use it effectively and extend it for your needs.
Architecture Overview
┌────────────────────────────────────────────────────┐
│ vx CLI │
│ vx <runtime> [args] │ vx run <script> │
└──────────┬─────────────┴───────────────┬────────────┘
│ │
┌─────▼──────┐ ┌───────▼────────┐
│ Resolver │ │ Script Engine │
│ (deps + │ │ (interpolation │
│ versions) │ │ + .env) │
└─────┬──────┘ └───────┬────────┘
│ │
┌─────▼──────────────────────────────▼──────┐
│ Provider Registry │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Node │ │ Python │ │ Go │ ... │
│ │Provider│ │Provider│ │Provider│ │
│ └───┬────┘ └───┬────┘ └───┬────┘ │
│ │ │ │ │
│ ┌───▼──┐ ┌────▼───┐ ┌───▼──┐ │
│ │node │ │python │ │ go │ ... │
│ │npm │ │uv │ │gofmt │ │
│ │npx │ │uvx │ └──────┘ │
│ └──────┘ └────────┘ │
└──────────────────────┬────────────────────┘
│
┌──────────────────────▼────────────────────┐
│ Content-Addressed Store │
│ ~/.vx/store/<runtime>/<version>/ │
└───────────────────────────────────────────┘Provider
A Provider is a module that supplies one or more related runtimes. It is the organizational unit in vx.
Provider (e.g., NodeProvider)
├── Runtime: node (Node.js runtime)
├── Runtime: npm (Node package manager)
└── Runtime: npx (Node package executor)Each provider handles:
- Version discovery — fetching available versions from upstream
- Installation — downloading and extracting binaries
- Execution — running commands with the correct environment
- Platform support — handling OS/architecture differences
Built-in Providers
vx ships with 48+ built-in providers covering major ecosystems:
| Ecosystem | Providers |
|---|---|
| Node.js | node, npm, npx, pnpm, yarn, bun |
| Python | python, uv, uvx |
| Go | go, gofmt |
| Rust | rust (rustc, cargo, rustup) |
| .NET | dotnet, msbuild, nuget |
| DevOps | terraform, kubectl, helm, docker |
| Cloud | awscli, azcli, gcloud |
| Build | cmake, ninja, just, task, make, meson, protoc |
| Media | ffmpeg, imagemagick |
| AI | ollama |
| Other | git, jq, deno, zig, java, gh, curl, pwsh... |
Manifest-Driven Providers
You can define custom providers using TOML manifests without writing Rust code:
# ~/.vx/providers/mytool/provider.toml
[provider]
name = "mytool"
description = "My custom tool"
[[runtimes]]
name = "mytool"
executable = "mytool"
description = "My awesome tool"
[runtimes.version_source]
type = "github_releases"
owner = "myorg"
repo = "mytool"See Manifest-Driven Providers for details.
Runtime
A Runtime is a single executable tool managed by a provider. Each runtime has:
- Name — primary identifier (e.g.,
node,python,go) - Aliases — alternative names (e.g.,
nodejs→node,golang→go) - Ecosystem — the ecosystem it belongs to (Node.js, Python, Go, etc.)
- Dependencies — other runtimes it requires (e.g.,
npmdepends onnode)
Runtime Dependencies
vx automatically resolves and installs dependencies:
npm ──depends on──> node
npx ──depends on──> node
uvx ──depends on──> uv
cargo ──depends on──> rust
gofmt ──depends on──> goWhen you run vx npm install, vx ensures Node.js is installed first.
Version Resolution
vx supports multiple version specification formats:
| Format | Example | Description |
|---|---|---|
| Exact | 22.11.0 | Specific version |
| Major | 22 | Latest 22.x.x |
| Minor | 22.11 | Latest 22.11.x |
| Range | ^22.0.0 | Compatible with 22.x.x |
| Range | ~22.11.0 | Compatible with 22.11.x |
| Latest | latest | Latest stable release |
| LTS | lts | Latest LTS release (Node.js) |
| Channel | stable / beta / nightly | Release channels (Rust) |
Version Resolution Order
When determining which version to use, vx checks in this order:
- Command line —
vx install node@22 - Environment variable —
VX_NODE_VERSION=22 - Project config —
vx.tomlin current or parent directory - Lock file —
vx.lockfor exact pinned versions - Global config —
~/.config/vx/config.toml - Auto-detect — latest stable version
Content-Addressed Store
All tools are stored in a global content-addressed store:
~/.vx/
├── store/ # Global tool storage
│ ├── node/
│ │ ├── 22.11.0/ # Complete installation
│ │ └── 20.18.0/
│ ├── python/
│ │ └── 3.12.8/
│ └── go/
│ └── 1.23.4/
├── cache/ # Download cache
│ └── downloads/
├── bin/ # Global shims
└── config/ # ConfigurationBenefits
- Deduplicated — same version stored only once, shared across projects
- Isolated — each version in its own directory, no conflicts
- Fast — environments created via symlinks, not copies
- Recoverable —
vx setupre-installs fromvx.toml
Project Configuration
A vx.toml file defines the project's tool requirements:
[tools]
node = "22"
python = "3.12"
uv = "latest"
just = "latest"
[scripts]
dev = "vx node server.js"
test = "vx uv run pytest"
lint = "vx uvx ruff check ."
build = "vx node scripts/build.js"
[env]
NODE_ENV = "development"See Configuration for the complete reference.
Execution Model
When you run vx <tool> [args...]:
- Tool lookup — finds the provider that manages the tool
- Version resolution — determines which version to use
- Dependency check — ensures all dependencies are available
- Auto-install — installs missing tools if
auto_installis enabled - Environment setup — sets PATH and environment variables
- Forward execution — runs the tool with the original arguments
- Exit code passthrough — returns the tool's exit code
The execution is transparent — tools behave exactly as if run directly.
Ecosystem
An Ecosystem groups related tools together:
| Ecosystem | Tools |
|---|---|
NodeJs | node, npm, npx, yarn, pnpm, bun, vite, deno |
Python | python, uv, uvx, pip |
Rust | rust, cargo, rustc, rustup |
Go | go, gofmt |
DotNet | dotnet, msbuild, nuget |
System | git, jq, curl, pwsh |
Ecosystems help vx understand relationships between tools and optimize dependency resolution.
Next Steps
- Direct Execution — How command forwarding works
- Version Management — Advanced version control
- Project Environments — Team collaboration
- CLI Reference — Complete command documentation