Safeguard
DevSecOps

How to Install Ruby on Mac: A Practical, Secure Setup Guide

The right way to install Ruby on a Mac is with a version manager, not the system Ruby. Here is a clean setup for current Ruby and even legacy 2.7 projects.

Marcus Chen
DevSecOps Engineer
5 min read

The correct way to install Ruby on a Mac is with a version manager such as rbenv or asdf — never by modifying the Ruby that ships with macOS. The system Ruby exists for Apple's own tooling, it is often outdated, and installing gems into it with sudo is how people end up with a broken toolchain and a machine that is hard to reason about. This guide walks through a clean install of Ruby on a Mac, running multiple versions side by side, handling a legacy 2.7 project, and getting Rails going, with the security notes that matter along the way.

Why not use the system Ruby

If you run ruby -v on a fresh Mac you will get a version Apple ships, and on recent macOS it lags well behind the current stable release (the Ruby 3.4 line at the time of writing). Two problems follow. First, it is old, so you miss language features, performance work, and — the part that matters for security — patched releases. Second, writing to it requires elevated permissions, and getting into the habit of sudo gem install means you are running third-party install scripts as root. A per-user version manager sidesteps both issues.

The recommended path: Homebrew plus rbenv

This is the setup most Ruby developers on macOS converge on. Install Homebrew if you do not have it, then install rbenv and a Ruby build backend:

brew install rbenv ruby-build

Wire rbenv into your shell. For the default zsh on modern macOS:

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

Now install a current Ruby and set it as your global default:

rbenv install 3.4.2
rbenv global 3.4.2
ruby -v   # => ruby 3.4.2

which ruby should now point inside ~/.rbenv/shims, not /usr/bin/ruby. That confirms you are on the managed version and leaving the system one untouched.

Running multiple Ruby versions

The whole point of a manager is that different projects can pin different versions. rbenv reads a .ruby-version file in the project directory:

cd my-project
rbenv install 3.3.6
rbenv local 3.3.6   # writes .ruby-version
ruby -v             # => 3.3.6 in this folder only

Commit .ruby-version so teammates and CI resolve the same interpreter. This is also where reproducibility and security meet: pinning the interpreter is the first step toward a build that produces the same result everywhere.

Installing legacy Ruby 2.7 on a Mac

Sometimes you inherit a project that still needs Ruby 2.7. You can install it the same way:

rbenv install 2.7.8

But be honest about what you are doing. Ruby 2.7 reached end of life in March 2023, meaning it no longer receives security patches. Running an EOL interpreter is a standing risk: any vulnerability found in it after that date stays unfixed. Use 2.7 only to keep a legacy app breathing while you plan the upgrade to a supported line, and never expose an EOL Ruby to untrusted input in production if you can avoid it. On Apple Silicon you may also hit build errors compiling old versions and need OpenSSL flags passed to ruby-build; that friction is itself a signal the version is past its time.

Installing Ruby on Rails on a Mac

Once Ruby is in place, Rails is just a gem:

gem install rails
rails -v
rails new myapp

Because you are on a managed, per-user Ruby, no sudo is needed — that is exactly the outcome you want. Use Bundler to pin your gem versions per project:

cd myapp
bundle install

Bundler writes a Gemfile.lock that records the exact resolved versions of every gem and its dependencies. Commit that lock file. It is the artifact that makes your dependency set auditable, and it is what a dependency scanner reads to tell you whether anything in your tree has a known advisory.

Keep the dependency tree honest

Installing Ruby cleanly is step one; the ongoing risk lives in the gems. A Rails app can pull in hundreds of transitive dependencies, and a vulnerability three levels deep is easy to miss by eye. Scanning your Gemfile.lock against a vulnerability database catches those, and an SCA tool such as Safeguard can flag a vulnerable transitive gem and point you at the fix. Our SCA product page covers how that works for Ruby and other ecosystems, and the Safeguard Academy has a walkthrough on reading and acting on dependency findings.

FAQ

Should I use rbenv, rvm, or asdf on macOS?

Any of them works. rbenv is minimal and popular, asdf is handy if you also manage Node or Python versions, and rvm is the older heavyweight. The important thing is that you use one of them rather than the system Ruby.

How do I install a specific Ruby version like 2.7 on a Mac?

Run rbenv install 2.7.8. Note that Ruby 2.7 is end of life as of March 2023 and gets no security patches, so use it only for legacy maintenance while you plan an upgrade.

Do I need sudo to install gems on a Mac?

No, and you should not. When Ruby is installed per-user through a version manager, gem install writes into your user directory. Needing sudo is a sign you are installing into the system Ruby, which you want to avoid.

How do I set a default Ruby version?

Use rbenv global 3.4.2 for a machine-wide default and rbenv local 3.3.6 inside a project to pin that directory. The local setting writes a .ruby-version file you should commit.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.