Manage Node.js Versions Using asdf

A unified version manager for Node.js and other runtimes. Install, switch, and standardize Node.js versions across your projects and team.

Introduction: The Version Management Challenge

Modern web development demands flexibility. Your Next.js application might require Node.js 20 for its latest features, while a legacy project still needs Node.js 14 to function. Without proper version management, you're stuck choosing between breaking existing projects or missing out on new capabilities. This is where asdf proves invaluable.

asdf is a universal version manager that handles multiple runtime versions through a single CLI tool. Unlike version managers that specialize in a single technology, asdf uses a plugin architecture to manage Node.js, Python, Ruby, Go, and dozens of other tools. For web development teams working with Next.js, React applications, and Node.js backends, asdf provides a unified approach to environment management that eliminates the complexity of juggling multiple version managers.

The tool works by creating shims--lightweight executables that intercept commands and route them to the correct version based on your project configuration. When you run node in a project directory, asdf determines which version to use by reading a .tool-versions file, installing it if necessary, and executing the command. This happens transparently, so your build scripts and development workflows remain unchanged.

Why asdf Over Other Node.js Version Managers

Traditional Node.js version managers like nvm have served developers well, but they come with limitations. nvm only manages Node.js, meaning you need separate tools for Python, Ruby, or Go. Each tool has its own commands, configuration files, and quirks to learn. asdf consolidates these into a single interface, reducing cognitive overhead and simplifying your development environment.

The plugin architecture means you install asdf once, then add only the plugins you need. Your .tool-versions file becomes a single source of truth for all tool versions in a project. Team members can onboard quickly because the version management experience is consistent regardless of which languages a project uses.

Prerequisites for This Guide

Before diving into asdf, ensure you have the necessary dependencies installed. asdf primarily requires git for cloning plugin repositories and downloading version archives. On Linux systems, you'll need a package manager like apt or dnf. On macOS, Homebrew handles most dependencies. The specific requirements vary by plugin--for the Node.js plugin, you'll also need curl and gpg for secure downloads. Refer to the asdf-vm official documentation for complete dependency details.

Installing asdf

Method 1: Homebrew Installation (Recommended for macOS and Linux)

The simplest installation method uses Homebrew, which handles most configuration automatically:

brew install asdf

This command downloads the latest asdf formula and prepares it for use. After installation, you'll need to add asdf to your shell configuration, which we'll cover in the shell configuration section.

Method 2: Package Manager Installation

Linux users can install asdf through their distribution's package manager:

# Arch Linux (AUR)
git clone https://aur.archlinux.org/asdf-vm.git
cd asdf-vm && makepkg -si

# Debian/Ubuntu
apt install asdf

These methods integrate asdf with your system's package management, making updates straightforward.

Method 3: Manual Installation

For maximum control or systems without package managers, install asdf manually:

# Clone the repository at a specific version
git clone https://github.com/asdf-vm/asdf.git --branch v0.18.0 ~/.asdf

# Add to your shell (see configuration below)

Manual installation gives you precise control over where asdf lives on your system and which version you run. This approach works well in containerized environments or CI/CD pipelines where you need reproducible setup scripts. See the asdf-vm installation guide for complete details.

Configuring Your Shell

After installing asdf, you must configure your shell to recognize the asdf shims directory. This ensures commands like node route through asdf's version resolution system.

Bash Configuration

For Bash users, add the following to ~/.bash_profile:

export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"

If you want shell completions for better command suggestions:

# Add to ~/.bashrc instead
. <(asdf completion bash)

Restart your terminal or run source ~/.bash_profile to apply changes.

ZSH Configuration

ZSH users modify ~/.zshrc:

export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"

# For completions, create the completions directory first
mkdir -p "${ASDF_DATA_DIR:-$HOME/.asdf}/completions"
asdf completion zsh > "${ASDF_DATA_DIR:-$HOME/.asdf}/completions/_asdf"

# Add to .zshrc
fpath=(${ASDF_DATA_DIR:-$HOME/.asdf}/completions $fpath)
autoload -Uz compinit && compinit

macOS Catalina and later use ZSH as the default shell, making this configuration essential for most Mac users. The asdf-vm documentation provides shell-specific configuration details.

Fish Shell Configuration

Fish users add to ~/.config/fish/config.fish:

if test -z $ASDF_DATA_DIR
 set _asdf_shims "$HOME/.asdf/shims"
else
 set _asdf_shims "$ASDF_DATA_DIR/shims"
end

if not contains $_asdf_shims $PATH
 set -gx PATH --prepend $_asdf_shims
end
set --erase _asdf_shims

# Completions
asdf completion fish > ~/.config/fish/completions/asdf.fish

Fish's configuration syntax differs from POSIX shells, so these commands use Fish-specific syntax. The completion setup ensures you get command suggestions when typing asdf commands.

Verifying Your Installation

After configuration, verify asdf works:

asdf --version

This should output the version number without errors. If you see "command not found," double-check your shell configuration and ensure you restarted your terminal session.

Installing the Node.js Plugin

asdf becomes useful only after you install plugins for the tools you need. The Node.js plugin, called asdf-nodejs, enables Node.js version management.

Plugin Dependencies

Before installing the plugin, ensure you have the required dependencies:

# Debian/Ubuntu
apt-get install dirmngr gpg curl gawk

# CentOS/Rocky Linux/AlmaLinux
yum install gnupg2 curl gawk

# macOS
brew install gpg gawk

These packages handle GPG key verification (essential for Node.js downloads), HTTP requests, and text processing. Installing dependencies before the plugin prevents post-install hook failures. The asdf-nodejs repository documents all dependencies required for the Node.js plugin.

Adding the Node.js Plugin

Install the plugin from its GitHub repository:

asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git

The plugin adds Node.js version management capabilities to asdf. You can verify installation:

asdf plugin list

This should show nodejs in the list of installed plugins. The plugin periodically updates to support new Node.js versions and fix compatibility issues.

Updating Plugins

Keep plugins updated to access new features and version support:

asdf plugin update nodejs

For all plugins at once:

asdf plugin update --all

Regular updates ensure you can install the latest Node.js releases and benefit from plugin improvements.

Installing Node.js Versions

With the plugin installed, you can now install specific Node.js versions. asdf downloads versions from official sources and installs them locally.

Listing Available Versions

Before installing, see which versions are available:

# List all available Node.js versions
asdf list all nodejs

# Filter to a specific major version
asdf list all nodejs 20
asdf list all nodejs 18

This shows stable releases, LTS versions, and current releases. Node.js follows a predictable release schedule with major versions every year and LTS versions every other year. The LogRocket tutorial on asdf provides practical examples of version listing and installation.

Installing a Specific Version

Install the version you need:

# Install a specific version
asdf install nodejs 20.8.0

# Install the latest available version
asdf install nodejs latest

The latest keyword resolves to the actual version number at installation time. This provides a convenient way to always use the newest version while maintaining reproducible installs when you specify exact versions.

Installing Multiple Versions

You can have multiple versions installed simultaneously:

asdf install nodejs 18.20.0
asdf install nodejs 16.20.2
asdf install nodejs 20.8.0

asdf stores each version separately and switches between them based on your configuration. This enables easy testing across Node.js versions without reinstallation.

Viewing Installed Versions

See which versions you have installed:

asdf list nodejs

This shows all installed versions. The currently active version appears with an asterisk or other marker.

Setting Node.js Versions

Version setting determines which installed version asdf activates in different contexts. asdf supports global, local (per-project), and shell-level versions.

Global Version (System-Wide Default)

Set a global default that applies everywhere:

asdf global nodejs 20.8.0

This writes to ~/.tool-versions, creating it if necessary. The global version serves as a fallback when no project-specific version is set. Most developers use the latest LTS or current version as their global default.

Local Version (Project-Specific)

Set a version for your current project:

asdf local nodejs 20.8.0

This creates (or modifies) a .tool-versions file in your current directory. When you run node from this directory or any subdirectory, asdf uses the specified version. This file should be committed to version control so team members get the correct version automatically. The asdf documentation covers version setting in detail.

Understanding Version Resolution

asdf resolves versions by searching up the directory tree:

  1. First, check PWD/.tool-versions
  2. Then check parent directories
  3. Finally, check $HOME/.tool-versions
  4. If no version is found, show an error

This hierarchical resolution means you can have project-specific versions that override the global default. A project requiring Node.js 16 can have its own .tool-versions even if your global version is Node.js 20.

Checking Current Version

See which version asdf would use:

asdf current nodejs

This shows the resolved version and its source (local, global, or system). If no version is set, it indicates configuration is missing.

Shell-Level Override (Temporary)

For temporary testing without modifying files:

asdf shell nodejs 18.20.0

This sets the version for your current shell session only. Useful for quick tests or when you need to run commands with a different version momentarily.

Working with .tool-versions Files

The .tool-versions file is the heart of asdf's configuration. Understanding its format and best practices ensures smooth team collaboration.

File Format

A .tool-versions file lists tools and their versions:

nodejs 20.8.0
python 3.12.0
ruby 3.2.2

Each line specifies a tool name and version number. Comments use #:

nodejs 20.8.0 # Current LTS
python 3.12.0 # Latest stable

Version Specification Formats

Versions can be specified in multiple ways:

nodejs 20.8.0 # Exact version
nodejs 20 # Major version only (uses latest 20.x)
nodejs latest # Latest available
nodejs lts # Latest LTS release

Using major versions or latest provides flexibility but can introduce inconsistency across team members. For production projects, exact versions ensure reproducibility.

Migrating from Other Version Managers

asdf supports existing version files from other managers. Enable legacy file support:

echo "legacy_version_file = yes" >> ~/.asdfrc

With this enabled, asdf recognizes:

  • .nvmrc for Node.js
  • .node-version for Node.js
  • .ruby-version for Ruby

This simplifies migration from nvm, rbenv, or similar tools, as documented in the asdf-vm configuration guide.

Committing to Version Control

The .tool-versions file belongs in version control:

git add .tool-versions
git commit -m "Add asdf version configuration"

When teammates clone the repository, asdf automatically installs and uses the specified versions. This eliminates "it works on my machine" issues caused by version mismatches.

Best Practices for Teams

Consistent Environments Across the Team

Team-wide consistency prevents subtle bugs that only appear with specific Node.js versions. When your web development team establishes standardized tooling, onboarding new developers becomes seamless and reduces environment-related issues.

  1. Use exact versions in .tool-versions
  2. Commit the file to version control
  3. Document Node.js requirements in your README
  4. Add asdf installation to onboarding documentation

CI/CD Integration

Continuous integration pipelines need the same versions as development machines. For teams implementing AI-powered automation workflows, consistent environments across CI/CD ensure reliable deployments:

# GitHub Actions example
- name: Setup asdf
 uses: asdf-vm/actions/setup@v2

- name: Install Node.js
 run: asdf install

- name: Run tests
 run: npm test

The asdf-vm/actions/setup action handles asdf installation and plugin setup. The asdf install command reads .tool-versions and installs all required versions. This integration pattern is recommended for CI/CD workflows using asdf.

Docker and Container Considerations

In Docker containers, install asdf during image build:

# Install asdf
RUN git clone https://github.com/asdf-vm/asdf.git /root/.asdf --branch v0.18.0
RUN echo ". /root/.asdf/asdf.bash" >> /root/.bashrc

# Add Node.js plugin
RUN . /root/.asdf/asdf.bash && asdf plugin add nodejs

# Install Node.js version
COPY .tool-versions /app/
RUN . /root/.asdf/asdf.bash && asdf install

This ensures containers use the same versions as development environments, maintaining consistency across development, testing, and production.

Plugin Management at Scale

For projects using multiple languages:

# Install all plugins from .tool-versions
asdf plugin add nodejs
asdf plugin add python
asdf plugin add ruby

# Install all versions
asdf install

Install all plugins first, then run asdf install to process .tool-versions and install each tool's specified version.

Troubleshooting Common Issues

Version Not Found Error

v: No version set for plugin nodejs

This means asdf can't find a version in any .tool-versions file. Solve by setting a version:

asdf local nodejs 20.8.0

Shims Not Working

If commands aren't routing through asdf:

# Verify asdf is in your PATH
type -a node

# Should show something like:
# node is /Users/you/.asdf/shims/node

If the PATH entry is missing, re-check your shell configuration and restart your terminal.

Plugin Installation Fails

Plugin installation might fail due to missing dependencies:

# Ensure all Node.js plugin dependencies are installed
brew install gpg gawk # macOS
apt-get install dirmngr gpg curl gawk # Debian/Ubuntu

Also verify git is available and you have network connectivity to GitHub.

Cleanup Unused Versions

Remove versions you no longer need:

asdf uninstall nodejs 16.20.2

This frees disk space while keeping other versions intact.

Advanced Usage

Reshimming After Installation

After installing a version, you might need to regenerate shims:

asdf reshim nodejs 20.8.0

This creates or updates the shim executables for the specified version. Normally automatic, but useful when shims become corrupted or after manual installation.

Using .asdfrc Configuration

Customize asdf behavior in ~/.asdfrc:

legacy_version_file = yes
use_release_candidate = yes
always_defer_to_downloads_for = nodejs

These settings enable legacy file support, allow release candidate versions, and configure download behavior per plugin.

Checking for Updates

# Check asdf version
asdf --version

# Update asdf core (for manual installations)
cd ~/.asdf && git pull

# Update all plugins
asdf plugin update --all

Regular updates keep you current with bug fixes and new features. Check the asdf-vm releases page for the latest version information.

Conclusion

asdf provides a unified, reliable approach to managing Node.js and other runtime versions. By centralizing version management across all your tools, it simplifies environment configuration for individual developers and teams alike. The .tool-versions file becomes a single source of truth that ensures consistent environments from development through production.

For modern web development workflows--especially those involving Next.js, React, and Node.js backends--asdf eliminates version conflicts and streamlines onboarding. New team members run asdf install and immediately have the correct versions. CI/CD pipelines build with confidence knowing local and remote environments match. Whether you're building complex web applications or implementing automated deployment pipelines, asdf ensures your development environment remains consistent and reliable.

Start by installing asdf, adding the Node.js plugin, and creating a .tool-versions file for your current project. Your future self will thank you when version upgrades become straightforward and "it works on my machine" becomes a relic of the past.

Need Help Setting Up Your Development Environment?

Our web development team can help you establish efficient workflows with modern tooling like asdf, Next.js, and CI/CD pipelines.