How to override macOS system Ruby

Hi, new to nix. I went through and Tidying up your $HOME with Nix and I’m excited by what I see, except that I can’t manage to update my global Ruby version. I can see the bin in the .nix-profile directory, but I am not sure how to set my system ruby to it.

$ type ruby
ruby is /usr/bin/ruby

$ ruby -v
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin22]

$ ls -la /Users/brian/.nix-profile/bin/ | rg ruby
lrwxr-xr-x    1 root  wheel    65 Dec 31  1969 bundle -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/bundle
lrwxr-xr-x    1 root  wheel    66 Dec 31  1969 bundler -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/bundler
lrwxr-xr-x    1 root  wheel    62 Dec 31  1969 erb -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/erb
lrwxr-xr-x    1 root  wheel    62 Dec 31  1969 gem -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/gem
lrwxr-xr-x    1 root  wheel    62 Dec 31  1969 irb -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/irb
lrwxr-xr-x    1 root  wheel    63 Dec 31  1969 racc -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/racc
lrwxr-xr-x    1 root  wheel    63 Dec 31  1969 rake -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/rake
lrwxr-xr-x    1 root  wheel    62 Dec 31  1969 rbs -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/rbs
lrwxr-xr-x    1 root  wheel    63 Dec 31  1969 rdbg -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/rdbg
lrwxr-xr-x    1 root  wheel    63 Dec 31  1969 rdoc -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/rdoc
lrwxr-xr-x    1 root  wheel    61 Dec 31  1969 ri -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/ri
lrwxr-xr-x    1 root  wheel    63 Dec 31  1969 ruby -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/ruby
lrwxr-xr-x    1 root  wheel    67 Dec 31  1969 typeprof -> /nix/store/jnxamzpz35ria8v333bmpgdccsfqm312-ruby-3.1.2/bin/typeprof

I have the following files in /Users/brian/.config/nixpkgs:

├── flake.lock
├── flake.nix
├── gitconfig
├── home.nix
└── zshrc

The important ones are probably flake.nix:

  description = "Home Manager configuration";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
    home-manager = {
      url = "github:nix-community/home-manager";
      inputs.nixpkgs.follows = "nixpkgs";

  outputs = { nixpkgs, home-manager, ... }: let
    arch = "aarch64-darwin"; # or aarch64-darwin
  in {
    defaultPackage.${arch} =

    homeConfigurations.brian =
      home-manager.lib.homeManagerConfiguration {
        pkgs = nixpkgs.legacyPackages.${arch};
        modules = [ ./home.nix ];

and home.nix:

{ pkgs, ... }: {
  home.username = "brian"; # REPLACE ME
  home.homeDirectory = "/Users/brian"; # REPLACE
  home.stateVersion = "22.11";
  programs.home-manager.enable = true;

  programs.git = {
    enable = true;
    includes = [{ path = "~/.config/nixpkgs/gitconfig"; }];

  home.packages = [

  programs.zsh = {
    enable = true;
    initExtra = builtins.readFile ./zshrc;

I’m using the Determinate Systems nix installer and home-manager. Is there an easy fix for this?

If the system ruby is still first, nix’s directories are likely at the wrong end of your PATH.

See if type -a ruby also reports the nix ruby.

I am not sure if this is the installer’s doing, or something in the shell init files on your system.

1 Like
❯ type -a ruby
ruby is /usr/bin/ruby
ruby is /Users/brian/.nix-profile/bin/ruby

❯ echo $PATH
/* a bunch of default paths */:/Library/Apple/usr/bin:/Users/brian/.nix-profile/bin:/nix/var/nix/profiles/default/bin

Looks like it can find it! But the nix paths are all the way at the end. So is there a nix-y way to fix this or should I just muck with $PATH? Or perhaps is this an issue I should take up the Determinate Systems installer?

EDIT - I can’t for the life of me find out where this $PATH modification occurred

Ah. I think I see what’s going on.

In a ~typical environment, your PATH would look something like:


I haven’t used the detsys installer yet, but it looks like it adds statements that source the canonical shell init hooks that nix uses.

But it is, unlike the canonical installer, adding the shell init hooks for zsh to /etc/zshenv instead of /etc/zshrc. They’re probably doing this to try to workaround macOS updates overwriting /etc/zshrc and evicting us (which is an ongoing papercut…).

But zsh will source /etc/zshenv earlier in the process, and the stock macOS init files (I think this happens in /etc/zprofile) will run /usr/libexec/path_helper which (helpfully…) mucks up the order of the PATH, as you can see below:

$ PATH=/Users/brian/.nix-profile/bin:/nix/var/nix/profiles/default/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin /usr/libexec/path_helper
PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/brian/.nix-profile/bin:/nix/var/nix/profiles/default/bin"; export PATH;
1 Like

(It’s possible detsys made an intentional choice that being at the end of the PATH would be better than getting evicted…)

1 Like

Ah! You found my issue on GitHub, too. I think for now I will just hack prepend the paths in my zshrc. Thank you for the additional context and help!

in ~/.zshrc, or /etc/zshrc?

Both are technically fine, but if you use the latter make sure to remember that Apple have a habit of overwriting it during macOS updates for the past few years now.

Ah! You found my issue on GitHub, too.

Hehe. I was going there to see if anyone had reported this already :slight_smile:

1 Like