Overview
asdf is a CLI tool for managing multiple runtime versions through a unified interface. The asdf-ruby plugin extends asdf to handle Ruby installation, switching, and version management across projects. asdf replaces traditional Ruby version managers like rbenv and rvm with a single tool that can manage Ruby alongside other programming languages.
The asdf-ruby plugin uses ruby-build internally to compile and install Ruby versions. It supports automatic version switching through .tool-versions
files and maintains compatibility with existing .ruby-version
files from other version managers. asdf stores each Ruby installation in isolated directories, preventing conflicts between versions.
asdf-ruby integrates with shell environments to modify PATH and environment variables automatically when changing directories. The plugin supports custom compilation options, patch application during builds, and provides commands for listing available versions, installed versions, and current active versions.
# Check current Ruby version
system("asdf current ruby")
# => ruby 3.2.1 /Users/developer/project/.tool-versions
# List installed Ruby versions
system("asdf list ruby")
# => 3.1.4
# 3.2.1
# 3.3.0
# Install specific Ruby version
system("asdf install ruby 3.2.1")
The plugin handles Ruby compilation dependencies and provides detailed error reporting when installations fail. It supports both global and local version configuration, with local versions taking precedence over global settings.
Basic Usage
Install asdf and the Ruby plugin before managing Ruby versions. The installation process varies by operating system but typically involves adding asdf to your shell configuration and installing the ruby plugin.
# Install asdf (macOS with Homebrew)
brew install asdf
# Add to shell configuration
echo -e "\n. $(brew --prefix asdf)/libexec/asdf.sh" >> ~/.bash_profile
# Install Ruby plugin
asdf plugin add ruby https://github.com/asdf-vm/asdf-ruby.git
List available Ruby versions to see what can be installed. The list includes stable releases, preview versions, and development snapshots. Filter the list to find specific version patterns or recent releases.
# List all available Ruby versions
asdf list-all ruby
# Install a specific version
asdf install ruby 3.2.1
# Install the latest stable version
asdf install ruby latest
# Set global default version
asdf global ruby 3.2.1
# Set local version for current project
asdf local ruby 3.1.4
Version switching happens automatically when entering directories with .tool-versions
files. The file contains version specifications for each tool managed by asdf. Create these files to pin Ruby versions for specific projects.
# Create .tool-versions file
echo "ruby 3.2.1" > .tool-versions
# Verify current version
asdf current ruby
# => ruby 3.2.1 /Users/developer/project/.tool-versions
Use shell integration to temporarily override versions for single commands or shell sessions. This is useful for testing code against different Ruby versions without changing project configurations.
# Temporary version for current shell session
asdf shell ruby 3.3.0
# Run single command with specific version
ASDF_RUBY_VERSION=3.1.4 ruby script.rb
The plugin supports legacy version files from other Ruby version managers. Enable this feature to read existing .ruby-version
files automatically without converting projects to .tool-versions
format.
# Enable legacy version file support
echo "legacy_version_file = yes" >> ~/.asdfrc
Production Patterns
Production deployments require careful consideration of Ruby version consistency across environments. Use .tool-versions
files to ensure development, staging, and production environments use identical Ruby versions. Docker containers and CI/CD pipelines should install asdf and restore the exact Ruby version specified in project files.
# Dockerfile with asdf Ruby
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y git curl build-essential
RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
RUN echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc
# Install Ruby plugin
RUN ~/.asdf/bin/asdf plugin add ruby
# Copy project files and install Ruby version
COPY .tool-versions /app/.tool-versions
WORKDIR /app
RUN ~/.asdf/bin/asdf install ruby
Configure deployment scripts to verify Ruby versions before running applications. This prevents runtime errors from version mismatches between development and production environments.
#!/usr/bin/env ruby
# deployment/verify_ruby.rb
required_version = File.read('.tool-versions').match(/ruby\s+(.+)/).to_a[1]
current_version = RUBY_VERSION
unless required_version == current_version
puts "ERROR: Ruby version mismatch"
puts "Required: #{required_version}"
puts "Current: #{current_version}"
exit 1
end
puts "Ruby version verified: #{current_version}"
Container orchestration platforms require asdf installation in base images or init containers. Use multi-stage builds to install asdf and Ruby versions in build stages, then copy the installations to runtime images.
# docker-compose.yml
version: '3.8'
services:
app:
build: .
environment:
- ASDF_DATA_DIR=/opt/asdf
volumes:
- .:/app
working_dir: /app
command: ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
Application servers and process managers need environment variable configuration to locate asdf-managed Ruby installations. Set PATH and ASDF environment variables in service configuration files.
# /etc/systemd/system/app.service
[Unit]
Description=Ruby Application
After=network.target
[Service]
Type=simple
User=deploy
WorkingDirectory=/home/deploy/app
Environment=ASDF_DATA_DIR=/home/deploy/.asdf
Environment=PATH=/home/deploy/.asdf/shims:/usr/local/bin:/usr/bin:/bin
ExecStart=/home/deploy/.asdf/shims/bundle exec rails server
Restart=on-failure
[Install]
WantedBy=multi-user.target
CI/CD pipelines require asdf installation and configuration in each job. Cache asdf installations and Ruby versions to reduce build times. Use matrix builds to test against multiple Ruby versions.
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby: [3.1.4, 3.2.1, 3.3.0]
steps:
- uses: actions/checkout@v4
- name: Install asdf
uses: asdf-vm/actions/setup@v3
- name: Cache asdf installations
uses: actions/cache@v3
with:
path: ~/.asdf
key: asdf-ruby-${{ matrix.ruby }}
- name: Install Ruby
run: |
asdf plugin add ruby
asdf install ruby ${{ matrix.ruby }}
asdf global ruby ${{ matrix.ruby }}
- name: Install dependencies
run: bundle install
- name: Run tests
run: bundle exec rspec
Error Handling & Debugging
Ruby installation failures typically stem from missing system dependencies or compilation errors. asdf-ruby requires development tools and libraries to compile Ruby from source. Install platform-specific dependencies before attempting Ruby installations.
# Ubuntu/Debian dependencies
sudo apt-get install -y build-essential libssl-dev libreadline-dev \
zlib1g-dev libyaml-dev libffi-dev
# macOS dependencies (with Homebrew)
brew install openssl readline libyaml gmp autoconf
# Check installation logs
asdf install ruby 3.2.1 2>&1 | tee ruby-install.log
Version resolution failures occur when asdf cannot find specified Ruby versions. The plugin maintains its own list of available versions that may lag behind Ruby releases. Update the plugin to refresh the version list.
# Update plugin to get latest Ruby versions
asdf plugin-update ruby
# List available versions
asdf list-all ruby | grep 3.2
# Verify version exists before installation
asdf list-all ruby | grep -q "3.2.1" && echo "Version available" || echo "Version not found"
Environment variable conflicts arise when multiple Ruby version managers coexist. Remove other version managers completely before using asdf-ruby to avoid PATH conflicts and version confusion.
# check_ruby_managers.rb
managers = {
rbenv: ENV['PATH'].include?('.rbenv'),
rvm: !ENV['rvm_path'].nil?,
chruby: ENV['PATH'].include?('.rubies'),
asdf: ENV['PATH'].include?('.asdf')
}
active_managers = managers.select { |name, active| active }
puts "Active Ruby managers: #{active_managers.keys.join(', ')}"
if active_managers.size > 1
puts "WARNING: Multiple Ruby version managers detected"
puts "This may cause version conflicts and unexpected behavior"
end
Build failures with custom configuration require environment variable inspection and compilation flag adjustment. Ruby compilation accepts numerous configuration options through environment variables.
# Debug compilation with verbose output
RUBY_CONFIGURE_OPTS="--enable-debug" MAKEFLAGS="-j1" asdf install ruby 3.2.1
# Common compilation options
RUBY_CONFIGURE_OPTS="--with-openssl-dir=$(brew --prefix openssl) --with-readline-dir=$(brew --prefix readline)" \
asdf install ruby 3.2.1
# Apply patches during installation
RUBY_APPLY_PATCHES="$HOME/ruby-patches/performance.patch" \
asdf install ruby 3.2.1
Permission errors occur when asdf directories have incorrect ownership or access rights. The asdf installation and plugin directories must be writable by the user running asdf commands.
# Fix asdf directory permissions
chmod -R 755 ~/.asdf
chown -R $(whoami) ~/.asdf
# Verify directory structure
ls -la ~/.asdf/
ls -la ~/.asdf/plugins/ruby/
Debugging version switching issues requires examining shell configuration and environment variables. asdf modifies PATH through shell integration scripts that must be properly sourced.
# Check asdf shell integration
echo $PATH | tr ':' '\n' | grep asdf
# Verify asdf function exists
type asdf
# Debug version resolution
ASDF_DEBUG=1 asdf current ruby
# Check .tool-versions file parsing
asdf current
Migration & Compatibility
Migrating from rbenv requires removing rbenv completely and converting project configurations. rbenv stores global version settings in ~/.ruby-version
and uses per-project .ruby-version
files. asdf can read these files when legacy support is enabled.
# Remove rbenv
brew uninstall rbenv
rm -rf ~/.rbenv
# Remove rbenv from shell configuration
# Edit ~/.bashrc, ~/.zshrc, etc. to remove rbenv lines
# Enable legacy version file support in asdf
echo "legacy_version_file = yes" >> ~/.asdfrc
# Verify existing .ruby-version files work
cd project_with_ruby_version
asdf current ruby
RVM migration involves removing the extensive RVM installation and converting gemsets to bundler-managed dependencies. RVM integrates deeply with shell configuration and may require manual cleanup of configuration files.
# Remove RVM completely
rvm implode
rm -rf ~/.rvm
# Clean shell configuration files
# Remove lines from ~/.bashrc, ~/.zshrc, ~/.profile
# Look for: [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
# Convert RVM gemsets to Gemfile dependencies
# Review installed gems: gem list
# Add required gems to Gemfile
The chruby migration process involves removing chruby and ruby-install, then installing equivalent Ruby versions through asdf-ruby. chruby stores Ruby installations in /opt/rubies
or ~/.rubies
directories.
# migration_script.rb
require 'fileutils'
# Find existing Ruby installations
ruby_dirs = Dir.glob('/opt/rubies/ruby-*') + Dir.glob("#{ENV['HOME']}/.rubies/ruby-*")
ruby_versions = ruby_dirs.map do |dir|
File.basename(dir).sub(/^ruby-/, '')
end
puts "Found Ruby versions from chruby:"
ruby_versions.each { |v| puts " #{v}" }
puts "\nTo install with asdf:"
ruby_versions.each do |version|
puts " asdf install ruby #{version}"
end
Version file format differences require attention when converting between tools. RVM uses .rvmrc
files with shell scripts, rbenv and chruby use simple version strings, and asdf uses .tool-versions
with tool/version pairs.
# Convert .rvmrc to .tool-versions
if [ -f .rvmrc ]; then
# Extract Ruby version from .rvmrc (simplified)
ruby_version=$(grep -o 'ruby-[0-9]\+\.[0-9]\+\.[0-9]\+' .rvmrc | head -1 | sed 's/ruby-//')
echo "ruby $ruby_version" > .tool-versions
echo "Converted .rvmrc to .tool-versions with Ruby $ruby_version"
fi
# Batch convert .ruby-version files to .tool-versions
find . -name .ruby-version -exec sh -c 'echo "ruby $(cat "$1")" > "$(dirname "$1")/.tool-versions"' _ {} \;
System Ruby conflicts arise when asdf-managed Ruby versions don't take precedence over system installations. Verify that asdf shims directory appears first in PATH and that system Ruby managers are completely removed.
# Check PATH order
echo $PATH | tr ':' '\n' | grep -n -E '(asdf|rbenv|rvm|ruby)'
# Verify Ruby location
which ruby
# Should show: /Users/username/.asdf/shims/ruby
# Check for system Ruby version managers
ls -la /usr/local/bin/ | grep -E '(rbenv|rvm)'
ls -la ~/.rbenv ~/.rvm 2>/dev/null || echo "No old managers found"
Gem environment migrations require installing bundler in each Ruby version and ensuring gem paths point to asdf-managed directories. Gems installed globally in previous version managers need reinstallation.
# check_gem_environment.rb
puts "Ruby version: #{RUBY_VERSION}"
puts "Gem home: #{Gem.dir}"
puts "Gem paths:"
Gem.path.each { |path| puts " #{path}" }
# Verify asdf gem paths
expected_path = File.expand_path("~/.asdf/installs/ruby/#{RUBY_VERSION}")
current_gem_home = Gem.dir
unless current_gem_home.start_with?(expected_path)
puts "WARNING: Gems not installed in asdf directory"
puts "Expected: #{expected_path}"
puts "Current: #{current_gem_home}"
end
Reference
Core Commands
Command | Parameters | Returns | Description |
---|---|---|---|
asdf install ruby <version> |
version (String) | Exit code | Install specified Ruby version |
asdf uninstall ruby <version> |
version (String) | Exit code | Remove specified Ruby version |
asdf list ruby |
None | Version list | Show installed Ruby versions |
asdf list-all ruby |
None | Version list | Show all available Ruby versions |
asdf global ruby <version> |
version (String) | Exit code | Set global default Ruby version |
asdf local ruby <version> |
version (String) | Exit code | Set local Ruby version for current directory |
asdf shell ruby <version> |
version (String) | Exit code | Set Ruby version for current shell session |
asdf current ruby |
None | Version info | Display current active Ruby version |
asdf where ruby <version> |
version (String) | Path | Show installation path for Ruby version |
asdf plugin-update ruby |
None | Exit code | Update ruby plugin to latest version |
Environment Variables
Variable | Purpose | Example Value |
---|---|---|
ASDF_RUBY_BUILD_VERSION |
Specify ruby-build version | v20231225 |
RUBY_CONFIGURE_OPTS |
Ruby compilation options | --with-openssl-dir=/opt/homebrew/opt/openssl |
RUBY_CFLAGS |
C compiler flags | -O2 -g |
MAKEFLAGS |
Make parallelization | -j4 |
RUBY_APPLY_PATCHES |
Patches to apply during build | /path/to/patch1.patch |
ASDF_RUBY_VERSION |
Override Ruby version | 3.2.1 |
ASDF_DATA_DIR |
asdf data directory | /home/user/.asdf |
Configuration Files
File | Location | Purpose |
---|---|---|
.tool-versions |
Project root | Local version specification |
~/.tool-versions |
Home directory | Global version defaults |
~/.asdfrc |
Home directory | asdf configuration |
.ruby-version |
Project root | Legacy version file (when enabled) |
Installation Paths
Component | Path |
---|---|
asdf installation | ~/.asdf/ |
Ruby installations | ~/.asdf/installs/ruby/ |
Ruby plugin | ~/.asdf/plugins/ruby/ |
Shims directory | ~/.asdf/shims/ |
Plugin repository | ~/.asdf/repository/ |
Version Formats
Format | Example | Description |
---|---|---|
Exact version | 3.2.1 |
Specific release version |
Latest stable | latest |
Most recent stable release |
Latest in series | latest:3.2 |
Most recent 3.2.x version |
Preview/RC | 3.3.0-preview1 |
Pre-release version |
Development | head |
Latest development snapshot |
Common Configuration Options
# ~/.asdfrc configuration options
legacy_version_file = yes # Enable .ruby-version support
use_release_candidates = no # Include RC versions in latest
always_keep_download = no # Keep source archives after install
plugin_repository_last_check_duration = 60 # Plugin update check interval
Build Dependencies by Platform
Platform | Required Packages |
---|---|
Ubuntu/Debian | build-essential libssl-dev libreadline-dev zlib1g-dev libyaml-dev libffi-dev |
CentOS/RHEL | gcc openssl-devel readline-devel zlib-devel libyaml-devel libffi-devel |
macOS | openssl readline libyaml gmp autoconf (via Homebrew) |
Alpine Linux | build-base linux-headers openssl-dev readline-dev zlib-dev yaml-dev libffi-dev |
Error Exit Codes
Code | Meaning |
---|---|
0 | Success |
1 | General error |
2 | Plugin not installed |
126 | Version not installed |
127 | Command not found |