Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, and more...



Differences Between RVM, Rbenv and RubyInstaller

In one of the latest blog posts, I've talked about the Differences Between Installers, Package Managers, and Dependency Managers. I said that in modern software development, it is almost impossible to create software without these tools because we have to take care of the different versions between different packages or libraries. 

As beginners, we tend to be confused about these terms: Installers, Package Managers and Dependency Managers, so for that reason, I wrote that post, and my suggestion for you is to read it before to continue, and with that, you can have the proper context about the current blog post.

Different ways to install Ruby

Usually, you'll have different projects that use different Ruby versions on your Operating System. For instance, you have Project A with the Ruby version 2.7.5, which belongs to a new side project you started to work on on weekends. And your company has been working on Project B with the Ruby 1.9.3 version (a legacy one), and they've never upgraded the project. How in the hell you'll deal with the different Ruby versions on your OS? Short answer: With the Package manager (Linux or Mac) or with the Installer (Windows)

So let's clarify some concepts:
  • If you use a package manager like RVM or Rbenv
  • * with a few commands, you can have different versions of Ruby in your OS. 
  • * you can switch any time and easily from one Ruby version to another. Even if you have some different projects running on different versions

  • If you use the Windows Installer
  • * you have to install the different Ruby versions by yourself each time you need it
  • * you need to make the switch manually between different versions, which is hard

Package managers will make your life easier and happier :)

RVM vs Rbenv

It's hard to say which one is most popular or better. We can say that both work almost the same way, but they use different commands. Honestly, I've seen more documents or tutorials of people who use RVM, but I think it is a more personal preference for each instructor. 

I found it more accessible and less buggy in some environments to work with Rbenv than RVM, like in Windows. However, in Linux and macOS, I found better and smooth results with RVM. We're going to use both here in two Operating Systems (Linux and Windows), so don't be shy to test both of them. 

1- RVM


Ruby Version Manager, often abbreviated as RVM, is a software platform for Unix-like operating systems designed to manage multiple installations of Ruby on the same device.

The entire ruby environment, including the Ruby interpreter, installed RubyGems, and documentation is partitioned. A developer can then switch between the different versions to work on several projects with varying version requirements. In addition to MRI (Matz's Ruby Interpreter), the standard Ruby interpreter, RVM functions as an installer for various other implementations of Ruby. These include JRuby, mruby, MacRuby, IronRuby, Maglev, Rubinius, Ruby Enterprise Edition, Topaz, and GoRuby (an interpreter optimized for code golf). In addition, RVM supports the installation of patched versions of MRI.

For a start, not only does RVM make installing multiple ruby interpreters/runtimes easy and consistent, it provides features such as gemsets that aren't typically supported out of the box on most ruby installs.

RVM also lets you use different rubies in a manner that won't mess with your existing ruby install (unless you tell it to), as well as allowing you to run multiple different rubies in separate terminals concurrently!

Gem sets
RVM gives you compartmentalized independent ruby setups. This means that ruby, gems, and IRB are all separate and self-contained - from the system and from each other.

You may even have separately named gemsets.

Let's say, for example, that you are testing two versions of a gem with ruby 2.1.1. You can install one to the default 2.1.1, then create a named gemset for the other version, and switch between them easily.

Note: don't run any of these commands yet; they're just explanatory

Example: testing gems

$ rvm 2.1.1@testing

will use a '2.1.1@testing' GEM_HOME (be sure to create it first), whereas:

$ rvm 2.1.1

will use the default 2.1.1 GEM_HOME

Example: Rails versions & upgrading apps

To illustrate the point, let's talk about an everyday use case. Assume you are testing out a rails application against a new Rails release. RVM makes such testing very easy by letting you quickly switch between multiple Rails versions. First, let's set up the environments:

$ rvm 2.1.1
$ gem install rails -v 4.1.0

$ rvm gemset create rails410 rails320
Gemset 'rails410' created.
Gemset 'rails320' created.

$ rvm 2.1.1@rails410
$ gem install rails -v 4.1.0

$ rvm 2.1.1@rails320
$ gem install rails -v 3.2.0

Note that you can have completely separate versions for each of the ruby installs above!

Now that your environments are set up, you can simply switch between Rails versions and Ruby versions as follows.

$ rvm 2.1.1@rails410 ; rails --version

Rails 4.1.0

$ rvm 2.1.1@rails320 ; rails --version

Rails 3.2.0

If you are deploying to a server, or you do not want to wait around for rdoc and ri to install for each gem, you can disable them for gem installs and updates. Just add the following line to your ~/.gemrc or /etc/gemrc:

gem: --no-rdoc --no-ri

Note: in this post, we're just reviewing the differences between RVM, Rbenv, and RubyInstaller. If you want to install RVM, follow the next blog post: Ruby Installation in Ubuntu Using RVM.

2- Rbenv


Compared to RVM, Rbenv does not manage gemsets nor install different Ruby versions. It only contains different ruby versions. So, tasks like installing different gemsets are now better off handled by other tools such as Bundler, which is a much better tool for managing dependencies in gems, and many gems these days are already using it. 

Both rbenv and RVM are Ruby version management tools. RVM is more resourceful, but Rbenv is lightweight, making it a strong contender for RVM. RVM manages and installs different versions of Ruby and gemsets on systems where Rbenv is a lightweight Ruby version management tool.

Rbenv does…
  • * Provide support for specifying application-specific Ruby versions.
  • * Let you change the global Ruby version on a per-user basis.
  • * Allow you to override the Ruby version with an environment variable.

In contrast with RVM, Rbenv does not…
  • * Need to be loaded into your shell. Instead, rbenv's shim approach works by adding a directory to your $PATH.
  • * Override shell commands like cd or require prompt hacks. That's dangerous and error-prone.
  • * Have a configuration file. There's nothing to configure except which version of Ruby you want to use.
  • * Install Ruby. You can build and install Ruby yourself or use ruby-build to automate the process.
  • * Manage gemsets. Bundler is a better way to manage application dependencies. If you have not yet used Bundler projects, you can install the rbenv-gemset plugin.
  • * Require changes to Ruby libraries for compatibility. The simplicity of rbenv means as long as it's in your $PATH, nothing else needs to know about it.

How does it work?
At a high level, Rbenv intercepts Ruby commands using shim executables injected into your PATH, determines which Ruby version has been specified by your application, and passes your orders along to the correct Ruby installation.

3- RubyInstaller for Windows


We have to say that you can install ruby directly without using RVM or Rbenv, but remember that these package managers help us deal with different versions of Ruby according to the project we're working on. As we learned, RVM is a Unix-based package, so we cannot use it directly on Windows. Something similar happens with Rbenv.

Ruby's difficulties on Windows stem from the fact that it's very different, under the covers, from both Linux and macOS. However, those two operating systems have similar "toolchains" because both are based on Unix. This means that they can use the same compiler, shared library system, and other tools to build the Ruby interpreter and Ruby libraries, called "RubyGems." or Gem Sets, as we learned with RVM.

Ruby is an open-source language written by volunteers. It was developed on Unix-based computers, so it came first to make the language work there. Then, of course, there's always been an effort to make it work on Windows as well, but the Unix-like environments got priority.

For many years, developing Ruby code on a Windows computer meant dealing with issues that someone using a Mac or Linux computer wouldn't face. To a certain extent, that's still true. However, when seeking help for a problem you run into, you'll likely find fewer search results for Windows. Plus, you may find that less common libraries don't even offer a Windows version.

And if you're planning on deploying your code, you should think about what that platform will be. For example, if you want to write a Ruby on Rails web application, you'll likely be deploying it onto a Linux web server. It's always best to keep the development environment close to the production environment so that you don't get any surprises when your code goes live.

One of the most surprising and pleasant developments in the software world in recent years has been Microsoft warming up to open source. They've also embraced open source by bringing Linux to Windows!

That's right, Windows 10 allows you to install a Linux "subsystem" on the same computer. This means you can install and run Linux applications. Unfortunately, this also means using Linux package managers to install the traditional Ruby environment. It's called the Windows Subsystem for Linux (WSL), but we're not going to cover it here; we're going to use Windows itself, given that we'll be running a Windows instance in AWS to demonstrate how to install it ruby right there.

However, if you have a computer running an older version of Windows, (WSL) isn't available to you. But fear not. There's still active development on Ruby for Windows, including right up to the most recent version of Ruby. This project is called RubyInstaller, and it works its magic by using the MSYS2 system for providing Unix-like libraries on Windows and MinGW (Minimal Gnu for Windows), which is an extensive library of Unix-like packages that work on Windows.

RubyInstaller is the most accessible and most widely-used Ruby environment on Windows. RubyInstaller combines the possibilities of native Windows programs with the rich UNIX toolset of MSYS2 and the large repository of MINGW libraries. 

As a result, RubyInstaller is a great way to use Ruby for development and production, especially if you just want to use Ruby for day-to-day scripting. 

Or if you require access to Windows resources such as hardware devices, DLLs, OLE, graphical user interfaces, or the GPU.

Although the Ruby community is continuously working to make the experience of using Ruby on Windows as smooth as possible, it's still slower and less convenient compared to Linux or macOS. Some of the shortcomings are specific Windows operating system internals (such as its poor shell support). Others are because so many Ruby developers simply prefer a UNIX-style system.

Ubuntu Linux or macOS are great as Ruby development platforms. They provide the best overall Ruby experience. If you use Ruby for a larger project, you might consider moving to one of those operating systems. Ruby is strong at cross-platform development, so it's easy to use Ruby on Linux for development and RubyInstaller on Windows in production or vice versa.

Windows Subsystem for Linux provides a Linux environment on top of Windows. Most of the development tools available for Linux can be used directly in WSL. It is well-suited for web development with Rails. It provides network and filesystem access, but access to hardware devices and interoperability with native Windows software is minimal. Ruby can be installed from the selected Linux distribution (typically Ubuntu) or through RVM or some similar Ruby version manager. WSL is not suitable for production use.

Cygwin is another alternative to RubyInstaller. It provides a POSIX environment on Windows. Ruby can be installed along with many other tools, but Cygwin cannot directly execute arbitrary Linux binaries (in contrast to WSL). Cygwin offers only a few advantages over RubyInstaller, such as a better shell and universal UTF-8 support. But it is slower and makes accessing Windows' native resources more difficult.

Note: in this post, we're just reviewing the differences between RVM, Rbenv, and RubyInstaller. If you want to actually install RVM, follow the next blog post: Ruby Installation in Windows Using RubyInstaller


* I think that the first decision you have to make is if you're going to work on a Unix-based system or a Windows System. With that decision, you can move forward. We suggest using a Unix-based system to work with Ruby, but if you have no choice, you can decide on WSL. But if you have to use native Windows components is better to use the RubyInstaller for Windows
* If you have Linux or macOS, you can install it automatically, directly, and globally using any of these package managers: RVM or Rbenv.
* If you have a Windows system, you need to install any Ruby version manually, directly, and globally to your operating system using an installer called RubyInstaller for Windows

Later, we're going to Install Ruby in a Unix-based and Windows system with all of these package managers and installers, so stay tuned.

Thanks for reading
Daniel Morales