Installing newer versions of Ruby on macOS using Homebrew is a common practice for developers needing specific language features or compatibility.
However, a frequent challenge arises when the system continues to use the pre-installed macOS Ruby version (often found at /usr/bin/ruby
) even after a successful Homebrew installation (e.g., brew install ruby
).
This situation prevents access to the features of the newer Ruby version and can cause issues with tools like Jekyll or when installing gems that require specific Ruby versions. This article examines the reasons behind this behavior and outlines several effective strategies based on common configuration practices to ensure the Homebrew-installed Ruby becomes the default in your shell environment.
Understanding the Root Cause: The PATH Environment Variable
The core reason the system Ruby might still be used lies in how the command-line shell locates executable programs. This process is governed by the PATH
environment variable.
- The
PATH
variable contains a list of directories, separated by colons. - When you type a command like
ruby
, the shell searches these directories *in the order they appear* in thePATH
. - The first directory containing an executable named
ruby
is the one that gets used.
macOS typically includes /usr/bin
(where the system Ruby resides) in the default PATH
. Homebrew usually installs its executables or creates symbolic links (symlinks) in /usr/local/bin
. If /usr/bin
appears earlier in your PATH
than /usr/local/bin
, the shell finds the system Ruby first and stops searching.
Furthermore, Homebrew sometimes installs certain software as “keg-only,” meaning it doesn’t automatically create the symlink in /usr/local/bin
, often because macOS provides its own version of that software (like Ruby). In such cases, even if /usr/local/bin
is first in your PATH
, the Homebrew Ruby executable isn’t found there directly, and additional configuration is required.
Read: Launching VS Code from the macOS Terminal: Resolving the code Command Issue
Solutions to Set the Homebrew Ruby as Default
Several approaches can resolve this issue, ranging from direct PATH manipulation to using version managers.
Solution 1: Modify PATH Precedence in Shell Profile
This method ensures that the Homebrew’s executables’ directory is listed *before* the system directories in your PATH
variable. This is typically done by editing your shell’s profile file.
- Identify your shell and profile file: Determine your current shell by running
echo $SHELL
.- If it returns
/bin/zsh
(common on newer macOS), you’ll likely edit~/.zshrc
. - If it returns
/bin/bash
(older macOS), you’ll likely edit~/.bash_profile
(or potentially~/.profile
if the former doesn’t exist).
- If it returns
- Edit the profile file: Add the following line to the *end* of the appropriate file (creating it if it doesn’t exist). This prepends the Homebrew binary directory to the existing PATH.
export PATH="/usr/local/bin:$PATH"
Alternatively, to specifically target the path where Homebrew installs Ruby (even if keg-only), use the path provided by Homebrew’s caveats (see Solution 4) or a dynamic approach:
# For Zsh (recommended for newer macOS) echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc # Or for Bash echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.bash_profile # A potentially more robust method using brew --prefix # echo 'export PATH="$(brew --prefix ruby)/bin:$PATH"' >> ~/.your_profile_file
Note: Some discussions mention adding the export line to
~/.zshenv
for Zsh as another alternative. - Reload the configuration: Apply the changes by either closing and reopening your terminal window/tab, or by running:
source ~/.zshrc # Or source ~/.bash_profile
This method directly tells the shell to look in Homebrew’s primary binary location first.
Read: 15 Proven Ways to Fix Wi-Fi Problems on Your Mac
Solution 2: Use `brew link` (If Applicable)
Homebrew uses linking to create symlinks from its installation directories (like /usr/local/opt/ruby
) to the general Homebrew binary directory (/usr/local/bin
). If Ruby was installed but not linked (perhaps as “keg-only”), you can attempt to force the link.
- Attempt to link Ruby:
brew link --overwrite ruby
- If needed, use force: In some cases, you might need to add the
--force
flag (use with caution):brew link --overwrite ruby --force
- Reload shell: Restart your terminal or source your profile file.
Important Consideration: Homebrew may intentionally refuse to link software like Ruby that macOS provides, displaying a warning like Warning: Refusing to link macOS provided/shadowed software: ruby
. In this scenario, modifying the PATH (Solution 1 or 4) is the recommended approach outlined in Homebrew’s own caveats.
Solution 3: Employ a Ruby Version Manager (rbenv)
For developers working with multiple Ruby projects that might require different Ruby versions, using a dedicated version manager like rbenv or RVM is a highly recommended practice. These tools manage multiple Ruby installations and make switching between them straightforward.
Steps using rbenv
(installable via Homebrew):
- Install rbenv and ruby-build:
brew update brew install rbenv ruby-build
- Install the desired Ruby version: (Replace `1.9.3-p125` with the specific version you need)
rbenv install 1.9.3-p125
- Set the global default Ruby version:
rbenv global 1.9.3-p125
- Configure shell integration: Ensure rbenv’s initialization command is added to your shell profile (
~/.zshrc
or~/.bash_profile
). Follow the instructions provided by `brew info rbenv` or the rbenv documentation, which usually involves adding a line like `eval “$(rbenv init -)”`. - Reload shell: Restart your terminal or source your profile file.
Version managers handle the PATH adjustments internally through “shims,” providing a cleaner way to manage different Ruby environments.
Solution 4: Directly Add Homebrew’s `opt` Path
When Homebrew installs a formula as “keg-only” (not linked into /usr/local/bin
), it often provides specific instructions (caveats) on how to add its dedicated path to your environment. This path usually resides within /usr/local/opt/
.
- Find the correct path: Homebrew typically installs Ruby (even specific versions) under
/usr/local/opt/
. The general path might be/usr/local/opt/ruby/bin
or a version-specific one like/usr/local/opt/ruby@2.7/bin
. You can check the output frombrew info ruby
or when (re)installing. - Add the path to your shell profile: Similar to Solution 1, add the export command to
~/.zshrc
or~/.bash_profile
:# Example for the generic path (adjust if needed) echo 'export PATH="/usr/local/opt/ruby/bin:$PATH"' >> ~/.zshrc # Example for a specific version # echo 'export PATH="/usr/local/opt/ruby@2.7/bin:$PATH"' >> ~/.zshrc
As mentioned before,
~/.zshenv
is also suggested as a place for such exports in Zsh environments. - Reload the shell: Restart your terminal or run
source ~/.your_profile_file
.
This directly prioritizes the specific Homebrew installation path, bypassing the need for linking into /usr/local/bin
.
Verification Steps
After applying a solution and reloading your shell configuration, verify that the correct Ruby version is now default:
- Check the active Ruby path:
which ruby
This should now point to a path within
/usr/local/
(e.g.,/usr/local/bin/ruby
or/usr/local/opt/ruby/bin/ruby
) or your version manager’s path (e.g., involving.rbenv/shims
). It should *not* show/usr/bin/ruby
. - Check the Ruby version:
ruby -v
This should display the version number you installed via Homebrew or the version manager.
- List all Ruby executables found in PATH (optional):
which -a ruby
This shows all occurrences of the `ruby` executable found by searching the directories in your `PATH`, listed in order of precedence. The desired Homebrew/version manager path should appear first.
Potential Issues and Considerations
- System Ruby and Gem Permissions: Attempting to install gems using the system Ruby (
/usr/bin/ruby
) often fails with permission errors (e.g.,Gem::FilePermissionError
). This is because the default system gem directory (e.g.,/Library/Ruby/Gems/...
) requires administrator privileges (sudo) to modify. Using the Homebrew-installed Ruby or a version manager typically installs gems into user-writable directories, avoiding this problem. This highlights a key reason for not using the system Ruby for active development. - Homebrew Link Failures: Remember that
brew link
might be intentionally blocked for Ruby. Check Homebrew’s output for warnings and prefer the PATH modification methods if linking is refused. - Compiler and Linker Flags: When installing gems that require compiling native extensions, you might need to tell the compiler where to find the Homebrew Ruby headers and libraries. Homebrew’s caveats often suggest setting environment variables like:
export LDFLAGS="-L/usr/local/opt/ruby/lib" export CPPFLAGS="-I/usr/local/opt/ruby/include"
(Adjust the path if using a version-specific formula like
ruby@2.7
). Similarly, `pkg-config` might need configuration:export PKG_CONFIG_PATH="/usr/local/opt/ruby/lib/pkgconfig"
These should also be added to your shell profile file (e.g.,
~/.zshrc
,~/.bash_profile
, or~/.zshenv
). - Shell Reload Required: Changes to shell profile files only take effect in new shell sessions or after manually reloading the configuration using
source ~/.your_profile_file
or fully restarting the terminal application (Cmd+Q
and reopen).
Conclusion
Ensuring that macOS uses a Homebrew-installed Ruby version instead of the system default primarily involves correcting the order of directories in the PATH
environment variable. This can be achieved by directly modifying the PATH in your shell profile (~/.zshrc
or ~/.bash_profile
), using Homebrew’s specific `opt` path, or employing a dedicated Ruby version manager like rbenv. While `brew link` is an option, it may be intentionally prevented for Ruby by Homebrew. Properly configuring the PATH ensures that the desired Ruby executable is found first by the shell, resolving version conflicts and enabling a smoother development workflow.
Frequently Asked Questions (FAQ)
Why shouldn’t I edit `/etc/paths` directly?
While technically possible, modifying the system-wide `/etc/paths` file is generally discouraged. Changes there affect all users and can potentially interfere with system operations or updates. Managing the PATH via user-specific profile files (like ~/.zshrc
or ~/.bash_profile
) is safer, more standard, and provides per-user control.
What is the difference between `.bash_profile`, `.bashrc`, and `.zshrc` / `.zshenv`?
These are shell configuration files. .bash_profile
is typically read by Bash for login shells (like opening a new terminal window), while .bashrc
is often for non-login shells. On macOS, interactive terminal shells usually act like login shells, making .bash_profile
the common choice for Bash PATH modifications. Zsh (the default on newer macOS) primarily uses ~/.zshrc
for interactive shell configuration. ~/.zshenv
is sourced earlier for all Zsh invocations and is sometimes suggested for environment variables like PATH, LDFLAGS, etc., though placing them in ~/.zshrc
is also very common and effective for interactive use.
Why might `brew link –overwrite ruby` fail or require `–force`?
Homebrew often prevents linking formulae that macOS provides system versions of (like Ruby) to avoid conflicts. This is indicated by a warning. The --force
flag overrides this protection but should be used cautiously as it could potentially cause unexpected behavior if not fully understood. Using the PATH modification method is generally preferred when Homebrew refuses to link.
Should I use RVM or rbenv?
Both RVM (Ruby Version Manager) and rbenv are popular tools for managing multiple Ruby versions. The discussion provided detailed steps for rbenv. Both achieve similar goals but use slightly different mechanisms (RVM modifies the shell environment more extensively, while rbenv uses shims). The choice often comes down to personal preference or project requirements.
Is restarting the terminal always necessary after changing the PATH?
No, you don’t always need to fully restart the terminal application. You can apply the changes to your *current* shell session by running source ~/.your_profile_file
(e.g., source ~/.zshrc
). However, any *new* terminal windows or tabs you open after saving the profile file will automatically inherit the updated PATH. Restarting is a simple way to ensure all subsequent sessions use the new configuration.
When do I need to set `LDFLAGS`, `CPPFLAGS`, or `PKG_CONFIG_PATH`?
You typically need these environment variables when installing Ruby gems that include native C extensions (parts written in C that need to be compiled). These flags tell the compiler and linker where to find the necessary header files and libraries associated with the specific Homebrew Ruby version you intend to use for compiling the gem.
If you like the content, we would appreciate your support by buying us a coffee. Thank you so much for your visit and support.