Published 2022-02-12.
Last modified 2023-10-10.
Time to read: 7 minutes.
This article describes how to install Ruby for software development. A working Ruby development setup is necessary for using and developing Jekyll plugins, which are written in Ruby. Ruby is also useful for making special-purpose programmable web sites, and system programming.
The Ruby language is interesting and fun to work with, but the immediate value it provides comes from the large number of high-quality, open-source libraries available for free, which are known as “gems”.
Standalone or Version Manager?
Because Ruby applications are normally constructed from a collection of Ruby gems, the system that you installed Jekyll onto must store those gems somehow. There are several ways to install Ruby plugins, including standalone and virtualized installation using a version manager.
Why Virtualize Ruby?

It is better to use virtualized user- and project-specific Ruby instances, instead of working with a system-wide installation of Ruby. This allows you to install and upgrade Ruby packages without using supervisor privileges. Also, virtualized instances allows you to work on many different independent Ruby projects at the same time, without package version collisions.
Docker
is over-sold.
It adds unnecessary complexity to software projects.
Instead of virtualizing the entire software environment,
as docker
attempts to do,
virtualizing the Ruby programming environment as described in this article,
Python venv
,
or node.js nvm
are much easier and more productive approaches.
I think docker
has been pushed hard in the media because it is a gateway technology to
PaSS.
This is a trend that PaSS vendors like AWS and Azure want to encourage, but
customers are pushing back.
3 Choices For Installing Ruby
Three popular choices for installing the Ruby language exist that follow best practices, depending on your needs. Other choices exist, but the user communities are much smaller; follow the path less traveled at your peril. Note that only 5% of Ruby developers do not use a Ruby version manager in the image below:
Let’s consider 3 of the available options:
-
Install the current version of Ruby standalone, without a Ruby version manager.
This option might be most appropriate for a production Linux system that has the minimum amount of software installed.
It is the simplest option for Ubuntu and WSL.
This option is problematic for Macs, however, so read on for a better option.
If you use this option you will have to set the
GEM_HOME
environment variable, and add$GEM_HOME/bin
to thePATH
. -
As a regular user using the
rbenv
Ruby version manager. This is by far the most popular option for software developers, in part because it is lightweight, also because it works so well on Linux and Mac. This option does not require you to mess around with environment variables.
If you use a Mac, this option provides the best experience. Jump to this section. -
As a regular user using the
rvm
version manager.rvm
has more features thanrbenv
and is easier to install, but it is older and has features that are no longer required with modern versions of Ruby.rvm
also redefines some system commands, which can be awkward and confusing. Like therbenv
option, this option does not require you to mess around with environment variables.
The official Ruby installation instructions are inconsistent across different OSes. For example, the Ubuntu installation instructions for Ruby also installs the Ruby system headers, while the MacOS instructions do not mention the subject, even though they are required. Fear not, dear reader, I will tell you all in this post.
Regardless of how you install Ruby,
gems should never be installed by using elevated user privileges
(in other words, do not ever use sudo
).
Standalone Ruby
This is how to perform the first option described above: installing the current version of Ruby without a version manager.
Debian, Ubuntu, Etc.
These instructions apply if your computer has a Debian-derived Linux distro, such as Ubuntu.
The apt
package manager docs for the ruby-full
package
describe 3 other packages related to installing Ruby, all of which are included in ruby-full
:
ri
- Ruby Interactive reference
ruby
- Interpreter of object-oriented scripting language Ruby (default version)
ruby-full
- Includes
ruby-dev
, which contains header files for compiling extension modules for Ruby (default version)
Ubuntu 23.04 (Lunar Lobster) Update:
libyaml-dev
must be specified or psych
,
which is a transitive dependency of debug
,
will not be able to be installed.
$ sudo apt install git ruby-full libyaml-dev
Mac
Installing Xcode and the command line tools
needs to be done first because that installs gcc
,
which is required for building dependencies.
$ xcode-select --install $ sudo xcodebuild -license
You will also need to install XCode command line tools and the header files available from XCode:
- Start XCode.
- Select Preferences / Downloads.
- Click on Command Line Tools and install them.
- Restart the computer.
Install Homebrew, rbenv
and Ruby:
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" $ brew update $ brew install rbenv rbenv-gem-rehash
GEM_HOME and PATH
This section continues the discussion of how set up a standalone Ruby instance, without a version manager.
The official installation instructions describe how to install Ruby,
but do not mention setting GEM_HOME
or
the need to include $GEM_HOME/bin
into the PATH
.
If you are not using a Ruby version manager, you should:
- Create a directory to hold the gems:
Shell
$ mkdir $HOME/.gems
- Add the following to
~/.bashrc
,~/.bash_profile
or~/.zshrc
:Shellexport GEM_HOME=$HOME/.gems export PATH=$GEM_HOME/bin:$PATH
If you opt for a Ruby version manager such as rbenv
, described next,
there is no need to set GEM_HOME
or modify the PATH
.
About rbenv
Now we can discuss the second option,
using the rbenv
version manager to install and
maintain Ruby instances of various versions.
Rbenv
is pretty cool, and works very well.
A feature that delighted me the first time I encountered it:
If the file .ruby-version
exists in a top-level project directory,
rbenv
automagically ensures that version of Ruby is used for the project.
For example, to run Jekyll with Ruby 3.1.0 for a given website,
the file .ruby-version
just needs to exist in the top-level
git directory for the source code as shown:
$ cat .ruby-version 3.1.0
If the required version of Ruby is not available, an error is issued and execution stops:
rbenv: version '3.1.0' is not installed (set by /var/
However, this awkwardly-worded warning comes from the documentation:
rbenv
there,
you are likely doing something wrong.
Installing Rbenv
If you opted to install Ruby using rbenv
for any platform, including Linux and Mac,
follow the
rbenv
official installation instructions.
Unfortunately, I found a few errors and continuity gaps in the instructions.
Following is an annotated transcript of what I did to install on WSL/Ubuntu,
supplemented with notes for Mac.
Ubuntu 23.04 (Lunar Lobster) Update:
libyaml-dev
must be specified or psych
,
which is a transitive dependency of debug
,
will not be able to be installed.
$ sudo apt install git rbenv ruby-dev libyaml-dev Reading package lists... Done Building dependency tree... Done Reading state information... Done rbenv is already the newest version (1.1.2-1). 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
You still need to install ruby-build
before you can install Ruby itself, so please read on!
Using Rbenv
Here is the help information for rbenv
:
$ man rbenv RBENV(1) RBENV(1) NAME rbenv - Simple Ruby Version Management USAGE Initialize rbenv for your acccount: $ rbenv init $ echo 'eval "$(rbenv init -)"' >> ~/.bashrc # restart your shell after this Install different Ruby interpreters (requires the ruby‐build package): $ rbenv install 2.4.0 Switch between different Ruby interpreters: $ rbenv global 2.4.0 $ ruby -v ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux] $ rbenv global system $ ruby -v ruby [whatever version of Ruby Debian provides by default] The original rbenv README with a more comprehensive documentation, including all of the available commands, is available at /usr/share/doc/rbenv/README.md.gz ABOUT This manual page was written for the Debian system by Antonio Terceiro <terceiro@debian.org> and may be used by others. 2020‐12‐16 RBENV(1)
The rbenv
command-line help is more useful:
$ rbenv help Usage: rbenv <command> [<args>] Some useful rbenv commands are: commands List all available rbenv commands local Set or show the local application-specific Ruby version global Set or show the global Ruby version shell Set or show the shell-specific Ruby version install Install a Ruby version using ruby-build uninstall Uninstall a specific Ruby version rehash Rehash rbenv shims (run this after installing executables) version Show the current Ruby version and its origin versions List installed Ruby versions which Display the full path to an executable whence List all Ruby versions that contain the given executable See `rbenv help <command>' for information on a specific command. For full documentation, see: https://github.com/rbenv/rbenv#readme
Unfortunately, when you attempt to get a listing of all the available rbenv
commands,
you get this ridiculous excuse for a help message:
$ rbenv help commands Usage: rbenv commands [--sh|--no-sh] List all available rbenv commands
I happen to know that the first command that you should run is rbenv init
.
Lets see its help message:
$ rbenv help init Usage: eval "$(rbenv init - [--no-rehash] [<shell>])" Configure the shell environment for rbenv
Again, not the most informative help message.
Now bravely go ahead and initialize rbenv
, even though we are not quite sure what it does:
$ rbenv init # Load rbenv automatically by appending # the following to ~/.bashrc or ~/.bash_profile: export PATH="$HOME/.rbenv/shims:$PATH" source /usr/lib/rbenv/completions/rbenv.bash eval "$(rbenv init -)"
Contrary to what the instructions say, there is no need to put the following lines into
~/.bashrc
or ~/.bash_profile
.
I will show you why in a moment.
export PATH="$HOME/.rbenv/shims:$PATH" source /usr/lib/rbenv/completions/rbenv.bash
Also contrary to what the instructions say, there is no need to open another shell to run the magic incantation. I call it magic because it is not obvious what the incantation does or why it is needed. Simply type:
$ eval "$(rbenv init -)"
It is easy enough to learn what the incantation does; just run it without evaluating the output:
$ rbenv init - export PATH="/home/mslinn/.rbenv/shims:${PATH}" export RBENV_SHELL=jekyll command rbenv rehash 2>/dev/null rbenv() { local command command="${1:-}" if [ "$#" -gt 0 ]; then shift fi case "$command" in rehash|shell) eval "$(rbenv "sh-$command" "$@")";; *) command rbenv "$command" "$@";; esac }
Now we know that the magic incantation generates a bash script that does the following:
- Adds
~/.rbenv/shims
to thePATH
- Reads in bash tab completions for
rbenv
- Defines a bash function called
rbenv
that shadows the actualrbenv
command
Placing the magic incantation into ~/.bashrc
or ~/.bash_profile
causes the script to be regenerated each time a shell is opened.
Go ahead and do that.
Now you know why I said that the earlier instruction to place the following two lines into
~/.bashrc
or ~/.bash_profile
is redundant,
because the magic incantation does that.
export PATH="$HOME/.rbenv/shims:$PATH" source /usr/lib/rbenv/completions/rbenv.bash
Call the Doctor
Run the Doctor script
to verify all is well with rbenv
:
$ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/main/bin/rbenv-doctor | bash Checking for `rbenv' in PATH: /usr/bin/rbenv Checking for rbenv shims in PATH: OK Checking `rbenv install' support: not found Unless you plan to add Ruby versions manually, you should install ruby-build. Please refer to https://github.com/rbenv/ruby-build#installation Counting installed Ruby versions: none There aren’t any Ruby versions installed under ’/home/mslinn/.rbenv/versions’. You can install Ruby versions like so: rbenv install 2.7.1 Checking RubyGems settings: OK Auditing installed plugins: OK
Ruby-build
Ruby-build
is a command-line utility that makes it easy to install virtually any version of Ruby, from source.
It is available as a plugin for rbenv
that provides the rbenv install
command,
and also is provided as a standalone program.
I find that installing ruby-build
as an rbenv
plugin is the most flexible and portable option.
The following commands can be executed from any directory.
$ echo "$(rbenv root)" /home/mslinn/.rbenv $ mkdir -p "$(rbenv root)"/plugins $ ls "$(rbenv root)" plugins shims versions $ ls "$(rbenv root)"/shims bundle bundler erb gem irb racc racc2y rake rbs rdbg rdoc ri ruby typeprof y2racc $ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build Cloning into '/home/mslinn/.rbenv/plugins/ruby-build'... remote: Enumerating objects: 12063, done. remote: Counting objects: 100% (756/756), done. remote: Compressing objects: 100% (304/304), done. remote: Total 12063 (delta 481), reused 626 (delta 402), pack-reused 11307 Receiving objects: 100% (12063/12063), 2.54 MiB | 14.37 MiB/s, done. Resolving deltas: 100% (7948/7948), done.
To upgrade Ruby-build
at a later time,
run the following from any directory:
$ git -C "$(rbenv root)"/plugins/ruby-build pull
To list all available versions of Ruby:
$ rbenv install --list 3.0.6 3.1.4 3.2.2 jruby-9.4.5.0 mruby-3.2.0 picoruby-3.0.0 truffleruby-23.1.1 truffleruby+graalvm-23.1.1
Installing Ruby
I decided to install a recent version of Ruby, 3.1.0.
As you now know, it will install into ~/.rbenv/versions
.
Rbenv
builds Ruby using gcc
, instead of installing a prebuilt version.
$ rbenv install 3.1.0 Downloading ruby-3.1.0.tar.gz... -> https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.gz Installing ruby-3.1.0... Installed ruby-3.1.0 to /home/mslinn/.rbenv/versions/3.1.0
The build took 5 minutes, 11 seconds on a fast laptop with an M.2 SSD.
Unlike standalone Ruby, when using rbenv
there is no need to set GEM_HOME
.
Instead, the location of the gems is inferred by the currently active Ruby instance.
$ echo $GEM_HOME $ gem env home # System version of Ruby /var/lib/gems/2.7.0
The following command set Ruby 3.1.0 as the default version of Ruby. This setting is persistent.
$ rbenv global 3.1.0 $ rbenv rehash $ gem env home /home/mslinn/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0
Now gems can be installed into the currently active Ruby instance.
$ gem install bundler rake Fetching bundler-2.3.8.gem Successfully installed bundler-2.3.8 Parsing documentation for bundler-2.3.8 Installing ri documentation for bundler-2.3.8 Done installing documentation for bundler after 0 seconds Successfully installed rake-13.0.6 Parsing documentation for rake-13.0.6 Installing ri documentation for rake-13.0.6 Done installing documentation for rake after 0 seconds 2 gems installed
Lets discover information about these gems:
$ gem info -b rake bundler *** LOCAL GEMS *** rake (13.1.0) Authors: Hiroshi SHIBATA, Eric Hodel, Jim Weirich Homepage: https://github.com/ruby/rake License: MIT Installed at: /home/mslinn/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0 Rake is a Make-like program implemented in Ruby *** REMOTE GEMS *** rake (13.1.0) Authors: Hiroshi SHIBATA, Eric Hodel, Jim Weirich Homepage: https://github.com/ruby/rake Rake is a Make-like program implemented in Ruby *** LOCAL GEMS *** bundler (2.4.20) Authors: André Arko, Samuel Giddins, Colby Swandale, Hiroshi Shibata, David Rodríguez, Grey Baker, Stephanie Morillo, Chris Morris, James Wen, Tim Moore, André Medeiros, Jessica Lynn Suttles, Terence Lee, Carl Lerche, Yehuda Katz Homepage: https://bundler.io License: MIT Installed at: /home/mslinn/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0 The best way to manage your application's dependencies *** REMOTE GEMS *** bundler (2.4.22) Authors: André Arko, Samuel Giddins, Colby Swandale, Hiroshi Shibata, David Rodríguez, Grey Baker, Stephanie Morillo, Chris Morris, James Wen, Tim Moore, André Medeiros, Jessica Lynn Suttles, Terence Lee, Carl Lerche, Yehuda Katz Homepage: https://bundler.io The best way to manage your application's dependencies
Ruby Development Components
Common components for Ruby development include:
-
Bundler
provides the
bundle
command, which lets you define the libraries that a project needs. It will automatically resolve version conflicts and download all appropriate gems from the sources you provide.
Shell$ gem install bundler
-
rake
is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax.
Shell$ gem install rake
- A testing framework:
rspec
,minitest
,minispec
,bacon
,test::unit
,cucumber
,capybara
, etc.rspec
seems to be winning the war
If you are developing a web app:
- An app server: unicorn, puma, thin, mongrel
- Web server: nginx, apache httpd
- Ruby on Rails, Thin, etc.
Speeding up Gem Installations
New gems can be extremely slow to install.
You can speed up the process by ignoring
ri
and
rdoc
information.
To to that, create the file ~/.gemrc
containing:
install: --no-ri --no-rdoc update: --no-ri --no-rdoc
Of course, that means you will not have documentation locally available for the gems that you install or update after that.
About the Author

I, Mike Slinn, have been working with Ruby a long time now. Back in 2005 I was the product marketing manager at CodeGear (the company was formerly known as Borland) for their https://www.infoq.com/news/2007/05/codegear-ror-ide/ 3rd Rail IDE. 3rd Rail supported Ruby, and Ruby on Rails, at launch.
In 2006, I co-chaired the Silicon Valley Ruby Conference, on behalf of SD Forum in Silicon Valley. As you can see, I have the t-shirt. I was sole chairman of the 2007 Silicon Valley Ruby Conference.
Several court cases have come my way over the years in my capacity as a software expert witness. The court cases featured questions about IP misappropriation for Ruby on Rails programs. You can read about my experience as a software expert if that interests you.
I currently enjoy writing Jekyll plugins in Ruby for this website and others, and Ruby utilities.