In this article, I’ll compare the most popular version managers for Ruby on a Mac: Chruby, Rbenv, and RVM, as well as Asdf, a version manager for multiple languages, and Frum, a brand new version manager written in Rust. I’ll make recommendations based on what you’re most likely to need.
Pre-installed Ruby is Not for Developers
Folks who are new to Ruby are delighted to discover that Ruby comes pre-installed on macOS. They’re often disappointed when a more experienced developer tells them, “Don’t use the Mac system Ruby.” I’ve written elsewhere about the reasons. In short, the system Ruby is there for macOS, not for you. It’s fine for running utility scripts, but for development, the system Ruby is out of date and, if you’re not careful, installation of gems can lead to headaches (including system security violations).
Homebrew’s One Ruby Problem
Homebrew is the package manager that has become a near-standard for adding developer software to macOS. Homebrew makes it easy to install a new Ruby version to avoid relying on the system Ruby. But there are two problems with Homebrew. First, Homebrew’s Ruby version can be automatically and unexpectedly replaced by a newer version when other Homebrew packages are installed (a problem solved by
brew pin ruby). More importantly, Homebrew only lets you install one version of Ruby. If you’re developing or maintaining more than one project in Ruby, you’ll likely need to switch among Ruby versions. That’s where you’ll need a version manager.
Asdf for Multiple Languages
Asdf is a version manager that accommodates multiple languages. If you’re using Ruby to develop web applications with Rails 6, you’ll need to install Node and Yarn to build a Rails starter application. (Rails 7 may eliminate the need for Node, but that’s not yet certain at this time.)
So, for a Rails developer, Asdf is an ideal version manager. It will also serve you well if you develop applications in Python, Elixir, or many other languages (see a list of supported languages). Is there a downside to using Asdf? Just two. It uses shims to intercept common commands, which can make troubleshooting difficult. Also, it can be a little slow for some operations. If you’re developing in multiple languages, I recommend you try Asdf to see if you like it. Switch to Frum, the Ruby-only version manager written in Rust, if you find Asdf slows you down.
Ruby-only Version Managers
If you only intend to develop applications using Ruby, choose among the four Ruby-only version managers: Chruby, Frum, Rbenv, and RVM. Differences among the four lie in speed, complexity, and how each switches Ruby versions. Let’s look at the oldest first: RVM.
RVM was the first popular version manager for Ruby. It’s still maintained and widely used. RVM modifies the system
cd command to set environment variables when you change directories. To override the
cd command, the RVM installation script changes the shell configuration file (the
~/.zshrc file on newer Macs).
RVM properly displays environment variables to reveal the Ruby and gem version and location, which can help diagnose problems. However, RVM includes additional features such as gemsets. Gemsets are no longer needed, since Bundler was added to the core Ruby to manage gem dependencies. The additional complexity isn’t needed, so many developers have switched to a newer version manager such as Rbenv, Chruby, or Frum.
After installing Rbenv with Homebrew, you must modify your
~/.zshrc file so the Rbenv shims take precedence over ordinary Ruby commands. The shim calls the
rbenv exec command, which determines which version of Ruby to use before running any Ruby command.
Shims have two drawbacks. First, shims make troubleshooting more difficult by hiding the actual command. For example, the
which ruby command shows the Rbenv shim, not the actual Ruby version (you must set the
RBENV_DEBUG environment variable if you want to see the actual Ruby command). Second, a shim can add microseconds of delay to execution of a Ruby command. (Rbenv intervenes every time you run a Ruby command unlike RVM, which intervenes only when you change directories.) For developers who notice the delay, or don’t like the idea of shims, there is Chruby or Frum.
Chruby is not as well-known as RVM or Rbenv, but it’s championed by several prominent Ruby developers. Unlike RVM, it doesn’t override the
cd command. Unlike Rbenv or Asdf, it doesn’t intercept commands using shims. You’ll need to modify your
~/.zshrc file so Chruby runs in your local shell environment. There’s no need to modify your
$PATH, as Chruby does that for you, based on the Ruby version you’ve selected.
Chruby also sets certain environment variables for Ruby. That’s all that’s needed for Chruby to switch among Ruby versions. It works fine for troubleshooting with
which. I used Chruby for several years and had no problems with it. Chruby is a great choice, but you may want to try Frum, the newest Ruby version manager.
Frum is written in Rust, a good language for fast command-line execution of system software. Frum is new (released in early 2021). Unlike Asdf, Chruby, or Rbenv, it includes a built-in Ruby installer command so there’s no extra program needed to install Ruby. The installer is fast, and Frum requires no dependencies (it’s an all-in-one Rust executable you can install with Homebrew).
After you install Frum, you must modify your
~/.zshrc file so Frum runs in your local shell environment. Like the other version managers, it checks for a
.ruby-version file in a project directory and, if there’s no version specified for a project, it will default to a global Ruby version. There are no shims (unlike Asdf or Rbenv) and it doesn’t override the
cd command (unlike RVM). Though it’s new, I recommend it because it’s all-in-one and fast.
Installing a Version Manager for Ruby
I’ve written a complete guide to installing Ruby on Mac. In the guide, I provide instructions for:
- installing Ruby with Asdf
- installing Ruby with Frum
- installing Ruby with Chruby
- installing Ruby with Homebrew
If you want to explore RVM or Rbenv, see:
A Note about Docker
If you mention Ruby version managers, someone will likely say, “I use Docker.” Docker is a containerization tool that some developers use for version management. The primary use case for Docker is to create a reproducible virtual server that contains a configured version of any software dependency needed to run an application (language, databases, message queues). As such, it’s ideal for creating a “frozen” version of a development environment for deployment to a server.
You can also develop locally within a container, but it will run slower, require more memory, and add configuration complexity compared to a version manager. To keep things simple, I avoid Docker for local development unless an application is disturbingly complex.
You’re not just a casual Ruby user if you’re working on multiple projects in Ruby. Make sure you install a great version manager in your local development environment.
which command. If these drawbacks outweigh the convenience of managing multiple languages, I recommend using Frum to switch among your Ruby versions. Version managers should be simple and stay out of your way when you’re working.
Frequently Asked Questions (FAQs) about Ruby Version Managers for MacOS
What are the key differences between RVM and rbenv?
RVM (Ruby Version Manager) and rbenv are both tools to manage multiple versions of Ruby on your system. The key difference lies in their approach. RVM is more feature-rich and allows you to manage gemsets – a set of gems that are used for a specific Ruby application. On the other hand, rbenv is simpler and focuses only on switching Ruby versions. It doesn’t support gemsets but you can achieve similar functionality using a plugin called ruby-build.
How do I install a specific version of Ruby using RVM?
To install a specific version of Ruby using RVM, you can use the ‘rvm install’ command followed by the version number. For example, to install Ruby 2.6.3, you would use the command ‘rvm install 2.6.3’. Once installed, you can switch to this version using the ‘rvm use’ command, like ‘rvm use 2.6.3’.
Can I use both RVM and rbenv on the same system?
While it’s technically possible to have both RVM and rbenv installed on the same system, it’s generally not recommended. Both tools modify your shell environment and having both can lead to unexpected behavior. It’s best to choose one based on your needs and stick with it.
How do I uninstall a Ruby version using rbenv?
To uninstall a Ruby version using rbenv, you can use the ‘rbenv uninstall’ command followed by the version number. For example, to uninstall Ruby 2.6.3, you would use the command ‘rbenv uninstall 2.6.3’.
How do I set a default Ruby version with RVM?
To set a default Ruby version with RVM, you can use the ‘rvm –default use’ command followed by the version number. For example, to set Ruby 2.6.3 as the default, you would use the command ‘rvm –default use 2.6.3’.
How do I update rbenv and its plugins?
To update rbenv and its plugins, you can use git. Navigate to the rbenv directory in your terminal (usually ‘~/.rbenv’) and run ‘git pull’. Then, navigate to each plugin directory and do the same.
Can I use RVM or rbenv with other programming languages?
RVM and rbenv are specifically designed for managing Ruby versions. If you need to manage versions of other programming languages, you might want to look into tools like pyenv for Python or nvm for Node.js.
How do I list all installed Ruby versions with rbenv?
To list all installed Ruby versions with rbenv, you can use the ‘rbenv versions’ command. This will display a list of all Ruby versions that rbenv can use.
How do I handle gem dependencies with RVM?
RVM allows you to manage gem dependencies through the use of gemsets. You can create a gemset with the ‘rvm gemset create’ command, switch to it with the ‘rvm gemset use’ command, and then install gems as needed.
How do I install a new Ruby version with rbenv?
To install a new Ruby version with rbenv, you can use the ‘rbenv install’ command followed by the version number. For example, to install Ruby 2.6.3, you would use the command ‘rbenv install 2.6.3’.