Introduction
asdf is a universal version manager that replaces language-specific tools like nvm, pyenv, rbenv, and others with a single consistent interface. Through its plugin architecture, asdf supports managing versions of virtually any language runtime, CLI tool, or system dependency from one place. A .tool-versions file in your project root pins exact versions for every team member.
What asdf Does
- Manages multiple versions of programming languages, runtimes, and CLI tools through a unified CLI
- Uses a plugin system with community-maintained plugins for Node.js, Python, Ruby, Go, Rust, Java, and hundreds more
- Reads
.tool-versionsfiles per project directory to automatically switch to the correct version - Supports global, local, and shell-level version overrides for flexible workflow control
- Shims installed binaries so version switching is transparent to your shell and scripts
Architecture Overview
asdf installs each tool version into ~/.asdf/installs/<plugin>/<version>/ and creates shim scripts in ~/.asdf/shims/. When you run a command, the shim looks up the nearest .tool-versions file in the directory hierarchy to determine which version to execute. Plugins are Git repositories that define how to list, download, install, and verify each tool. The core is written in Bash (with a Go-based rewrite underway for asdf v0.15+).
Self-Hosting & Configuration
- Install via Homebrew, apt, or by cloning the Git repository into
~/.asdf - Source
asdf.shin your shell profile (bash, zsh, fish, elvish, or nushell) - Add plugins with
asdf plugin add <name>to enable managing that tool - Create a
.tool-versionsfile in your project root listing each tool and its pinned version - Configure fallback versions globally with
asdf global <name> <version>
Key Features
- Single CLI replaces nvm, pyenv, rbenv, rustup, sdkman, and dozens of other version managers
- Over 600 community plugins covering languages, databases, cloud CLIs, and DevOps tools
- Per-project
.tool-versionsfiles are committed to source control for reproducible environments - Legacy version file support reads
.nvmrc,.python-version,.ruby-versionautomatically - Completions available for bash, zsh, fish, and other modern shells
Comparison with Similar Tools
- mise (formerly rtx) — Rust-based asdf-compatible alternative with faster performance and built-in task running
- nvm — Node.js-only version manager; asdf covers Node.js plus every other language
- pyenv — Python-only version manager; asdf uses the same shim approach but for all languages
- fnm — Fast Node.js version manager written in Rust; single-language focus versus asdf's universal approach
- volta — JavaScript toolchain manager with speed focus; limited to Node.js and package manager versions
FAQ
Q: How many plugins does asdf support? A: The community maintains over 600 plugins covering everything from Node.js and Python to Terraform and kubectl.
Q: Can I use asdf alongside other version managers? A: Yes, but you should ensure asdf's shims directory appears first in your PATH to avoid conflicts.
Q: Is asdf slow? A: The Bash-based core can add small overhead to shell startup. The ongoing Go rewrite (v0.15+) and alternatives like mise address this.
Q: Does asdf work on Windows? A: asdf primarily targets Unix systems (macOS and Linux). On Windows, WSL2 is the recommended approach.