The Definitive Guide To Installing Ruby Gems on a Mac

A very common error people run into when trying to install any Ruby gem on macOS is a permissions error much like this one:

ERROR: While executing gem ... (Gem::FilePermissionError)
You don't have write permissions for the /Library/Ruby/Gems/2.6.0 directory

This can be very frustrating for newcomers, especially when the proposed solutions are inconsistent, wrong, or potentially dangerous. People face this error mainly due to incomplete documentation. As developers become more experienced, they tend to take certain things for granted, and forget to cultivate a beginner's mindset. Even popular gems like Rails are not immune to this. The Rails installation instructions imply that as long as you can run ruby -v and get version 2.5.0 or later, gem install rails should work, but it does not out of the box on a new macOS computer. It results in the error message above. This is the case for any gem you try to install on a Mac that has not yet been properly configured for Ruby development.

macOS returns this error because the default location for Ruby gem installations is the system Ruby directory that is preinstalled by Apple. That directory is not meant to be modified, hence Apple not giving us permissions to write to it.

So how can we install gems?

There are two main options: 1) install a separate version of Ruby that you control, or 2) keep using the system Ruby via some modifications. Option 1 can be further split into two options: install the new version with Homebrew, or with a Ruby manager.1

I highly recommend using a Ruby manager because it allows you to have multiple versions of Ruby installed at the same time, and makes it easy to switch between them. Even if you are using Ruby for the first time, it is worth your time to learn how to use a Ruby manager because you will inevitably need one as you progress.

Since the Ruby manager option is the one I recommend, we'll go over it first, and then I'll describe the other options so you can appreciate how complicated this can get, and why I wrote a script to automate it all.

Here are links to all the options:

Install Ruby with a manager [Recommended]

Install Ruby with Homebrew [OK, but not recommended]

Keep using the system Ruby by changing the installation path [Not recommended]

Keep using the system Ruby by overriding Apple's protection [Never do this!]

Install Ruby with a manager

At a high level, there are a minimum of five steps to a working Ruby environment on macOS with a Ruby manager:

  1. Install Homebrew (which also installs the prerequisite Apple command line developer tools)
  2. Install a Ruby manager
  3. Configure the Ruby manager
  4. Install a specific version of Ruby
  5. Switch to that version of Ruby

Luckily, these can all be automated, as I have done in my Ruby development setup scripts. One script only installs the minimum needed to use Ruby, and is meant for folks who know that's all they need. The other is what I recommend for most people, as it installs additional useful and necessary development tools, and is customizable.

The way the script is written, it only installs what you don't already have, and it upgrades any outdated tools, keeping your system up to date. It provides value continuously.

Ideally, every maintainer of a Ruby project would point their users to a script that can set everything up for them. Not only does it save time, but it virtually eliminates errors — and therefore discouragement — at such a critical time for beginners. It also saves the maintainers time thanks to a decrease in issues reported by users who are running into the permissions error.

In Badass: Making Users Awesome, Kathy Sierra makes two very important points:

Working on what stops people matters more than working on what entices them.

and

What's much much worse than a bad user manual? Making the user think the manual works just fine for everyone else.

Sadly, many projects don't provide prerequisite setup instructions. If they do, they are typically missing steps (as we've seen with Rails, or Sinatra, or Hanami), or the instructions are provided in an outdated video that doesn't match the written ones, or the user has to choose between various options, all of which involve manually running commands.

The biggest reason of all to provide a script, or at a minimum Homebrew + Ruby manager documentation, is that Apple will no longer be preinstalling Ruby on macOS2. It's not yet clear to me when that change will happen, but I encourage you to stay ahead of the curve, like Homebrew did at the beginning of 2020 when they rewrote their installation script in bash instead of Ruby.

This concludes the Ruby manager option for installing gems and working with Ruby in general. It's the only option I recommend for long-term happiness, but I've included other options below for completeness, and to explain things like PATH, the difference between .zshrc and .bash_profile, and sudo.

Install Ruby with Homebrew

This is similar to the previous option, but instead of installing a Ruby manager with Homebrew, you can install Ruby directly with Homebrew. Doing this manually involves three commands, followed by relaunching the Terminal:

# 1. Install Homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

# 2. Install the latest Ruby

brew install ruby

# 3. Update the `PATH` environment variable to point to Homebrew's Ruby
# installation. Replace .zshrc with .bash_profile if you're using bash.
# Read these two guides if some of this is not familiar:
# https://www.moncefbelyamani.com/which-shell-am-i-using-how-can-i-switch/
# https://www.moncefbelyamani.com/troubleshooting-command-not-found-in-the-terminal/

echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc

# 4. Relaunch your Terminal (or open a new tab)

To verify that you are using the Homebrew version of Ruby, run this command:

which ruby

You should see /usr/local/opt/ruby/bin/ruby.

If you don't, the two most likely reasons are that you didn't relaunch the Terminal, or the PATH is not set properly. See step 3 in the code box above. A misconfigured PATH is a common source of confusion and errors. Instructions for setting the PATH are abundant on the internet, but very few explain what PATH does and why it needs to be updated. Read my guide about PATH to learn more.

Now we can run gem install rails successfully. But wait! What happens if we try to use Rails? If you try rails -v for example, you'll get this error:

Rails is not currently installed on this system. To get the latest version,
simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.

What do you mean it's not installed? I can see it when I run gem list! In some cases, this could be due to not relaunching the Terminal (or opening a new tab). In this case though, it's because Homebrew installs gems in a particular directory that needs to be added to the PATH. But how did macOS recognize the rails command to begin with? That's because there is a rails command in /usr/bin that Apple preinstalls for some reason. That message with the shocking suggestion to use sudo comes from Apple, not Rails.

Other gems that don't already exist in /usr/bin will also fail to be found after being installed, but with a different message:

$ gem install jekyll
$ jekyll -v

zsh: command not found: jekyll

If you paid attention when you ran brew install ruby, you might have noticed this message:

By default, binaries installed by gem will be placed into:
  /usr/local/lib/ruby/gems/2.7.0/bin

You may want to add this to your PATH.

In general, Homebrew's messages are worth reading and very helpful. This one could be clearer and more explicit. I will send them a pull request and see what they think.

To wrap up this section, in order to be able to install gems and use them with a Homebrew Ruby installation, your PATH needs to include the location of the Homebrew Ruby, as well as the gems location:

export PATH="/usr/local/opt/ruby/bin:/usr/local/lib/ruby/gems/2.7.0/bin:$PATH"

The 2.7.0 above assumes Homebrew installed a Ruby version that starts with 2.7. If you're using a different version (which you can check with ruby -v), replace 2.7 with the first two digits of your Ruby version.

The downside to installing Ruby with Homebrew is that you can only use one version of Ruby at a time. Once you start working on multiple projects, each with its own supported version of Ruby, this quickly becomes unsustainable.

Keep using the system Ruby by changing the installation path

While Apple doesn't grant you write access to the system Ruby directory, RubyGems does provide a way to specify an alternative location for gem installations. You can do that in one of two ways:

gem install rails --user-install
gem: --user-install

In addition, to use the gems, you need to update the PATH in your ~/.zshrc or ~/.bash_profile:

export GEM_HOME="$HOME/.gem"
export PATH="$HOME/.gem/ruby/2.6.0/bin:$PATH"

The 2.6.0 above assumes you are on Catalina. For previous macOS versions, replace 2.6 with the first two digits of your system Ruby, which you can find by running ruby -v.

While this option will allow you to run gem install without getting permission errors, it won't guarantee that all gems will be able to install successfully. A typical error in this scenario looks something like this:

ERROR: Failed to build gem native extension

That's because some gems require certain developer tools that don't come preinstalled on macOS. Apple provides these tools as part of the Xcode app, but also as a standalone package called the Command Line Tools (CLT). The most recommended way to install the CLT is with this command:

xcode-select --install

Unfortunately, this doesn't always work. Sometimes, macOS displays this error:

Can't install the software because it is not currently available from the
Software Update server.

What does seem to work consistently is to install Homebrew, which detects whether or not the CLT are installed, and if not, it uses a different and more reliable command to fetch and install them.

Once Homebrew is installed, you should be able to install gems using the system Ruby. The downside to this option is similar to the one above in that you can only use one version of Ruby, but it's even worse because you are stuck with the version that came with macOS, and you can't upgrade it until a new major version of macOS comes out, once a year on average. But as mentioned above, Apple is no longer planning on preinstalling Ruby in future versions of macOS. As of today, the latest version you could possibly get from Apple is 2.6.3 via Catalina, while the current latest stable release is 2.7.2.

Keep using the system Ruby by overriding Apple's protection [DANGER!]

This involves elevating your privileges by using sudo, such as:

sudo gem install some_gem_you_should_not_install

Unfortunately, this is a common solution offered on the internet, either out of laziness, or unfamiliarity with better options. I advise you to stay far away from it for several reasons:

In addition, prefixing the gem install command with sudo on its own will not install all gems successfully on a Mac that doesn't have the command line tools installed.

It's never as simple as it seems, which is why I advocate for a proven and reliable script that can set everything up.


  1. Virtual machines, containers, and cloud services are other options, but in this post, I'm only focusing on installing directly on macOS. 

  2. Look for the "Scripting Language Runtimes" section.