When you need a unified way to install CRuby and alternative Ruby implementations these days, it comes down to ruby-build and ruby-install. Is there a difference?
A lot of people associate Ruby version managers and installers to be the same thing. One of the most popular Ruby version manager, RVM, does both, so that’s not surprising.
rbenv changed this assumption by simply focusing on a better way of switching rubies (by not replacing
cd in your shell with a shell function), leaving the task of getting and compiling Ruby to be a separate problem.
Read the Hacker News announcement of rbenv for nostalgia. It’s worth noting that rbenv came from folks from 37signals, now Basecamp and Hey, the company behind Ruby on Rails (originally written by Sam Stephenson).
This change of perspective gave birth to ruby-build. If installed as an rbenv plugin, it does the installation part for rbenv users. But at the same time, ruby-build is also a standalone program that can “just” install Ruby on your system.
Later on, chruby came as the simplest alternative to switching Ruby. And it came with ruby-build alternative called ruby-install as it’s a sister project for installing your rubies.
If you are looking for a simple way to install Ruby or JRuby, which one to choose today?
ruby-build (at the time of version
20200926) can be installed as:
$ git clone https://github.com/rbenv/ruby-build.git $ PREFIX=/usr/local sudo ./ruby-build/install.sh
I am not aware of prebuild system packages (such as RPM or DEB).
The usage is simple:
$ ruby-build --definitions # lists all available versions of Ruby $ ruby-build 2.7.1 ~/local/ruby-2.7.1 # installs Ruby 2.7.1 to ~/local/ruby-2.7.1
Besides the obvious, ruby-build can:
- install Ruby, JRuby, mruby, TruffleRuby, Rubinius, REE, Topaz,
- apply patches,
- verify checksums,
- and use custom build configuration
A small inconvenience is that ruby-build won’t handle the installation of any system pre-requisites such as C compiler and these have to be installed beforehand.
On Fedora with:
$ dnf install -y gcc make bzip2 openssl-devel libyaml-devel libffi-devel readline-devel zlib-devel gdbm-devel ncurses-devel autoconf bison ruby -y
Note I needed to add
ruby to the official list.
Why Ruby you ask? ruby-build builds CRuby from the GitHub repository and thus needs Ruby for
configure: error: cannot run /bin/sh tool/config.sub
This would not be needed when building from published archives.
A notable configuration change that many will want to do is to configure CRuby to use jemalloc (by passing
--with-jemalloc to the
./configure step). This can be done with:
$ RUBY_CONFIGURE_OPTS=--with-jemalloc ruby-build 2.7.1 ~/local/ruby-2.7.1
Note that similar to basic build packages, jemalloc would need to be installed as well. On Fedora:
$ sudo dnf install jemalloc-devel -y
The latest development version of Ruby (also called “trunk” or “HEAD”) can be installed by appending
$ ruby-build 3.0.0-dev ~/local/ruby-3.0.0-dev
All in all, ruby-install keeps things very simple. Apart from rbenv we can find it also powering the Ruby plugin for asdf (general multi-tool version manager). This makes it even more popular than it already is.
0.7.1) can be installed as:
$ wget -O ruby-install-0.7.1.tar.gz https://github.com/postmodern/ruby-install/archive/v0.7.1.tar.gz $ tar -xzvf ruby-install-0.7.1.tar.gz $ cd ruby-install-0.7.1/ $ sudo make install
For Fedora users, ruby-install (together with chruby) seems to be available as an RPM package on Copr. Note that there was an official Copr, but it seems discontinued for the time being.
The usage is similarly very simple:
$ ruby-install ruby # install latest stable Ruby $ ruby-install --latest # lists all available versions of Ruby $ ruby-install --install-dir ~/rubies/ruby-2.7.1 ruby # sets specific install dir
You can also use it for installing Ruby versions for RVM or rbenv by simply changing the paths to the following:
$ ruby-install --rubies-dir ~/.rvm/rubies ruby 2.7.1 # RVM default path $ ruby-install --install-dir ~/.rbenv/versions/2.7.1 ruby 2.7.1 # rbenv default path
- install Ruby, JRuby, mruby, TruffleRuby, and Rubinius.
- apply patches,
- verify checksums,
- use custom build configuration
- and even install dependencies via various system package managers
The list of what it can do is almost the same, unlike ruby-build it has default directories set and can use APT, DNF and brew to install what’s needed.
Very interesting is the anti-feature of not requiring update every time a new Ruby version comes out (ruby-build keeps all version recipes in
It might also be a reason why ruby-install unfortunately does not support installing trunk/HEAD, which is the only thing lacking behind ruby-build. (You can still install official previews such as
A custom build configuration for the
./configure step can be passed after the command itself:
$ ruby-install ruby 2.6 -- --with-jemalloc --enable-shared CFLAGS="-O3"
jemalloc is unfortunately not install automatically as other system dependencies for now so make sure to install jemalloc with header files (
jemalloc-devel package on Fedora).
As you can see, both ruby-build and ruby-install “do the trick.”
I would recommend choosing ruby-install for:
- your everyday development
- and building a production box
…mainly due to:
- not requiring Ruby (keeping the base system clean if necessary),
- not requiring updates for new releases,
- and conveniently installing system dependencies (apart from jemalloc for now)
I will most likely recommend ruby-install for deployment next to the prebuild packages in my upcoming book Deployment from Scratch.
I would stick to ruby-build if:
- I am already a user of rbenv or asdf for development
- or need to be building bleeding edge rubies
I am writing an introductory book on web application deployment. Networking, processes, systemd, backups, and all your usual suspects.