Back to Scaling Ruby Applications guides

Getting Started with rbenv

Stanley Ulili
Updated on September 30, 2025

Managing multiple Ruby versions across different projects can quickly become a headache. You might have one application running on Ruby 3.2, another requiring Ruby 2.7 for legacy support, and a new project using the latest Ruby 3.3 features. Switching between these versions manually is error-prone and time-consuming.

rbenv solves this problem by providing a lightweight, unobtrusive way to manage Ruby versions on your system. Unlike heavyweight solutions that modify your shell extensively or require complex configurations, rbenv takes a minimal approach that stays out of your way while giving you complete control over which Ruby version each project uses.

This guide will walk you through installing rbenv, understanding how it works, and using it effectively to manage Ruby versions across multiple projects.

Prerequisites

Before getting started with rbenv, you'll need a Unix-like operating system such as macOS or Linux. Windows users can use rbenv through WSL (Windows Subsystem for Linux). You should also have basic familiarity with the command line and text editors.

Unlike some other version managers, rbenv doesn't come with Ruby pre-installed. You'll install Ruby versions as needed, which keeps your system clean and gives you explicit control over what's installed.

Why use rbenv?

Before diving into installation, let's understand what makes rbenv an excellent choice for Ruby version management. Traditional approaches often modify your shell environment heavily or require activation scripts.

rbenv takes a different path by inserting executable scripts called "shims" at the front of your PATH. When you run a Ruby command, these shims intercept the call and delegate it to the appropriate Ruby version.

This design adds minimal overhead to your shell, works consistently across different shells, and switches Ruby versions automatically based on your current directory. rbenv follows the Unix philosophy of doing one thing well.

It manages Ruby versions and nothing else, leaving dependency management to Bundler. This focused approach makes rbenv reliable and simple to troubleshoot.Retry

Installing rbenv

In this section, you'll install rbenv and set up your shell environment to work with it. The installation process varies slightly depending on your operating system, but the end result is consistent across platforms.

The most reliable way to install rbenv on Linux is by cloning it directly from the official repository. This method works across all Linux distributions and gives you direct access to updates. Start by cloning rbenv into your home directory:

 
git clone https://github.com/rbenv/rbenv.git ~/.rbenv

Next, add rbenv to your PATH by updating your shell configuration. For bash users, run:

 
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc

If you're using zsh, use these commands instead:

 
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc

The first line adds rbenv's executable to your PATH, making the rbenv command available. The second line initializes rbenv's shim directory and shell integration, which enables automatic version switching based on your current directory.

After configuring your shell, apply the changes by restarting your terminal or sourcing your profile:

 
source ~/.bashrc

Now install ruby-build as a plugin. While rbenv manages version switching, ruby-build provides the actual installation capability through the rbenv install command:

 
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build

With ruby-build installed as a plugin, rbenv gains the ability to compile and install Ruby versions directly from source.

Verify that rbenv installed correctly:

 
rbenv --version
Output
rbenv 1.2.0

This output confirms rbenv is installed and accessible. You're now ready to start managing Ruby versions.

macOS users can alternatively install rbenv through Homebrew, which simplifies both installation and updates. If you have Homebrew available, run:

 
brew install rbenv ruby-build

This installs both rbenv itself and ruby-build in one command. After installation completes, add the initialization to your shell profile:

 
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc

Then apply the changes:

 
source ~/.zshrc

The Homebrew approach handles both rbenv and ruby-build installation automatically, making it the most convenient option for macOS users.

Understanding rbenv's operation

Now that rbenv is installed, let's understand how it works. This knowledge will help you use the tool effectively and troubleshoot issues.

When you run a Ruby command like ruby or gem, your shell searches your PATH environment variable for an executable. rbenv places a directory of shims at the front of your PATH, so these shims are found first.

Each shim determines which Ruby version should handle the command by checking several locations in order: first a RBENV_VERSION environment variable, then a .ruby-version file in the current directory (searching up through parent directories), and finally the global default version in ~/.rbenv/version.

Once determined, the shim delegates the command to the actual Ruby executable for that version. This happens transparently, so you're simply running ruby, but rbenv ensures the right version handles it.

This architecture lets you have multiple Ruby versions installed simultaneously without conflicts. Each version lives in its own directory under ~/.rbenv/versions/, completely isolated from the others..

Installing Ruby versions with rbenv

With rbenv configured, you're ready to install Ruby versions. Unlike package managers that provide pre-built binaries, rbenv compiles Ruby from source on your machine. This ensures compatibility with your system and allows for customization, though it does mean installations take a few minutes to complete.

Start by checking which Ruby versions are available for installation:

 
rbenv install --list

This command displays a long list of available Ruby versions, including stable releases, preview versions, and alternative Ruby implementations.

Output
3.2.9
3.3.9
3.4.6
jruby-10.0.2.0
mruby-3.4.0
picoruby-3.0.0
truffleruby-25.0.0
truffleruby+graalvm-25.0.0

The output shows versions in chronological order, with the most recent stable versions appearing near the end of the list.

To install the latest stable Ruby version, you can specify it explicitly. At the time of writing, Ruby 3.4.6 represents the current stable release:

 
rbenv install 3.4.6
Output
==> Installing ruby-3.4.6...

The installation process downloads the Ruby source code, compiles it with optimizations for your system, and installs it in rbenv's version directory. Depending on your machine's speed, this typically takes between two and five minutes.

You can install multiple Ruby versions side by side. For example, if you're maintaining a legacy application, you might need Ruby 2.7:

 
rbenv install 2.7.8

After installing versions, check what's available on your system:

 
rbenv versions
Output
* system
  2.7.8
  3.4.5
  3.4.6

The asterisk indicates which version is currently active. The "system" entry represents any Ruby version installed outside of rbenv, such as the version that shipped with your operating system.

Once you have Ruby versions installed, you need to tell rbenv which one to use. This is where rbenv's version selection comes into play.

Setting Ruby versions for your projects

In the previous section, you installed Ruby versions that are now available on your system. This section covers how to configure which version gets used in different contexts, from setting a system-wide default to specifying versions for individual projects.

When you first install rbenv, the "system" Ruby (if one exists) remains active. However, you'll want to set a default version that rbenv manages. This global version applies whenever you're not in a directory that specifies its own Ruby version:

 
rbenv global 3.4.6

After running this command, verify the change took effect:

 
ruby --version
Output
ruby 3.4.6 (2025-07-16 revision 20cda200d3) +PRISM [arm64-darwin24]

The global version works well for general development and new projects. However, the real power of rbenv emerges when you set project-specific versions. This ensures that each application runs on the exact Ruby version it was designed for, preventing subtle compatibility issues.

Navigate to a project directory or create a new one to explore this feature:

 
mkdir ruby-app && cd ruby-app

Set a specific Ruby version for this project:

 
rbenv local 3.2.9

This command creates a .ruby-version file in the current directory containing just the version number:

 
cat .ruby-version
Output
3.2.9

The .ruby-version file should be committed to version control alongside your project code. When other developers clone your repository and have rbenv installed, they'll automatically use the correct Ruby version when working in that directory. This eliminates the common "works on my machine" problem caused by version mismatches.

To see this automatic switching in action, navigate between directories with different Ruby versions. First, create another directory with a different version:

 
cd ..
 
mkdir legacy-app && cd legacy-app
 
rbenv local 2.7.8

Now move between the directories and check the active version:

 
cd ../ruby-app
 
ruby --version
Output
ruby 3.2.9 (2025-07-24 revision 8f611e0c46) [arm64-darwin24]
 
cd ../legacy-app
 
ruby --version
Output
ruby 2.7.8p225 (2023-03-30 revision 1f4d455848) [arm64-darwin24]

The Ruby version switches automatically as you move between projects. You never need to run activation commands or manually switch versions. rbenv handles everything based on the .ruby-version file it finds in each directory.

Managing gems with rbenv

Installing Ruby versions forms just one part of the development workflow. You also need to install gems, which are Ruby libraries and tools. rbenv integrates seamlessly with Ruby's gem system while maintaining isolation between different Ruby versions.

Each Ruby version you install through rbenv has its own independent gem environment. When you install a gem, it goes into the gem directory for the currently active Ruby version. This isolation prevents conflicts and ensures that different projects with different Ruby versions can use different gem versions without interfering with each other.

Let's install a gem to see how this works. Make sure you're in a directory using Ruby 3.4.6:

 
cd ../ruby-app
 
rbenv local 3.4.6
 
gem install rails
Output
...
Successfully installed rails-8.0.3

This installs the Rails framework into the gem directory for Ruby 3.4.6. After installing gems, you need to run an important command:

 
rbenv rehash

The rehash command regenerates rbenv's shims. When you install a gem that provides executable commands (like Rails provides the rails command), rbenv needs to create a corresponding shim. Without rehashing, the new command won't be available even though the gem is installed.

Verify that the Rails command is now available:

 
rails --version
Output
Rails 8.0.3

Now switch to a directory using a different Ruby version:

 
cd ../legacy-app
 
rails --version
Output
rbenv: rails: command not found

The `rails' command exists in these Ruby versions:
  3.4.6

Even though you just installed Rails, it's not available in the Ruby 2.7.8 environment. This demonstrates how rbenv maintains complete separation between Ruby versions and their gems.

One important detail about rbenv: modern versions include an automatic rehashing feature through the rbenv-gem-rehash plugin, which typically ships with rbenv. This plugin automatically rehashes after gem installations, so you rarely need to run rbenv rehash manually. However, if you install a gem and the command isn't available, running rehash explicitly will resolve the issue.

For managing project dependencies systematically, you should use Bundler rather than installing gems globally. Bundler works perfectly with rbenv and provides reproducible dependency management across your team.

Using Bundler with rbenv

While installing individual gems with gem install works for quick experiments, professional Ruby development relies on Bundler to manage dependencies. Bundler ensures everyone on your team uses the same gem versions, preventing subtle bugs caused by version differences.

Bundler comes pre-installed with modern Ruby versions, so you can start using it immediately. Create a new project directory to explore Bundler's features:

 
cd ..
 
mkdir demo-project && cd demo-project
 
rbenv local 3.4.6

Initialize a new Bundler configuration:

 
bundle init
Output
Writing new Gemfile to /Users/stanley/demo-project/Gemfile

This creates a Gemfile in your project directory. The Gemfile declares which gems your project depends on:

 
cat Gemfile
Output
# frozen_string_literal: true

source "https://rubygems.org"

# gem "rails"

Edit the Gemfile to add dependencies your project needs. For example, add the Sinatra web framework:

Gemfile
source "https://rubygems.org"

gem "sinatra", "~> 4.1"
gem "puma", "~> 6.5"

Install the dependencies:

 
bundle install
Output
Fetching gem metadata from https://rubygems.org/....
Resolving dependencies...
Fetching base64 0.3.0
Fetching logger 1.7.0
...
Installing mustermann 3.0.4
Fetching sinatra 4.1.1
Installing sinatra 4.1.1
Bundle complete! 2 Gemfile dependencies, 12 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

Bundler creates a Gemfile.lock file that records the exact versions of all gems installed, including transitive dependencies. This lock file should be committed to version control. When another developer clones your repository and runs bundle install, they'll get exactly the same gem versions you used.

Check which gems Bundler installed for your project:

 
bundle list
Output
Gems included by the bundle:
  * base64 (0.3.0)
  * logger (1.7.0)
  * mustermann (3.0.4)
  * nio4r (2.7.4)
  * puma (6.6.1)
  * rack (3.2.1)
  * rack-protection (4.1.1)
  * rack-session (2.1.1)
  * ruby2_keywords (0.0.5)
  * sinatra (4.1.1)
  * tilt (2.6.1)
Use `bundle info` to print more detailed information about a gem

The list shows all gems in your bundle, including dependencies that Sinatra and Puma require. Notice that installing just two gems brought in nine additional dependencies. Bundler handles this complexity automatically, ensuring all required gems are present and compatible.

To run Ruby commands with the gems from your Gemfile, prefix commands with bundle exec:

 
bundle exec ruby -r sinatra -e "puts Sinatra::VERSION"
Output
4.1.1
Sinatra could not start, the required gems weren't found!
Add them to your bundle with:
    bundle add rackup puma
or install them with:
    gem install rackup puma

The command successfully loads Sinatra and prints its version, but Sinatra's initialization code then checks for runtime dependencies. Even though puma exists in your Gemfile, Sinatra is also looking for rackup, which wasn't automatically included. This demonstrates how some gems have optional dependencies that you might need to add explicitly depending on your use case.

The bundle exec prefix ensures commands use the exact gem versions specified in your Gemfile.lock rather than any other versions that might be installed globally. This prevents version conflicts and ensures consistent behavior across different development environments.

Many Ruby developers create a shell alias to make this more convenient:

 
echo 'alias be="bundle exec"' >> ~/.bashrc
 
source ~/.bashrc

Now you can type be ruby script.rb instead of bundle exec ruby script.rb, saving keystrokes while maintaining the isolation that Bundler provides. This workflow becomes especially valuable when working on multiple projects with different gem versions.

Final thoughts

This guide covered the essential aspects of using rbenv to manage Ruby versions across your projects. You've seen how rbenv's lightweight architecture provides reliable version management without the complexity of heavier alternatives, how to install and switch between Ruby versions automatically, and how the tool integrates seamlessly with Bundler for complete environment isolation.

rbenv's philosophy of doing one thing well makes it a reliable foundation for Ruby development. By intercepting commands through shims rather than modifying your shell environment extensively, it provides the power you need while staying out of your way during normal development.

For more advanced usage and configuration options, consult the official rbenv documentation. The project's GitHub repository also contains helpful information about plugins that extend rbenv's capabilities for specialized workflows.

Thanks for reading!

Got an article suggestion? Let us know
Next article
Top 10 Ruby on Rails Alternatives for Web Development
Discover the top 10 Ruby on Rails alternatives. Compare Django, Laravel, Express.js, Spring Boot & more with detailed pros, cons & features.
Licensed under CC-BY-NC-SA

This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.