Set up Nix on macOS using flakes, nix-darwin and home-manager | Noghartt's garden (2024)

About three years ago, I started using NixOS on my personal laptop. In those days, Ineeded a config that would allow me to have a stable system, that could be reproducibleover all my machines, and that would allow me to have a development environment that wouldbe easy to maintain and to share with others. NixOS comes to fit all these requirements.

But, since I started using a MacBook Pro (2022), I do not feel the necessity of using theNix package manager, since I can use Homebrew to install all the packages that I need andhave some kind of reproducibility with shell scripts. But, for some needs, I would like touse Nix again on my macOS now, and this blog post will be about how to set up Nix on macOSlike me.

Installing Nix on macOS

Installing Nix on macOS is easy. You can use the following command to install Nix on yourmachine:

curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install

This command installs the Nix package manager based on the DeterminateSystem/nix-installer,based on the explanation by the Zero to Nix, it givesbetter error messages, an installation plan (like Terraform), and other cool features that bringa better installation experience for you.

Just follow the step by step of the installation flow and everything will be fine.

Creating the flake file

After installing Nix, you can create a flake.nix file that will be the entry point for yourentire Nix configuration on your machine. This file will be used to define the packages thatyou want to install, the system configuration, and the home-manager configuration.

{ description = "Nix configuration";  inputs = { nixpkgs.url = "github:NixOS/nixpkgs";  nix-darwin.url = "github:lnl7/nix-darwin/master"; nix-darwin.inputs.nixpkgs.follows = "nixpkgs";  home-manager.url = "github:nix-community/home-manager"; home-manager.inputs.nixpkgs.follows = "nixpkgs"; };  outputs = inputs @ { self, ... }: let nixpkgsConfig = { config.allowUnfree = true; }; in {  };}

This is the basic structure of my flake.nix, it defines all the inputs that I will needto use in my configuration, they are:

  • nixpkgs: The main NixOS/Nixpkgs repository, that will be used to define the packagesthat I want to install on my machine.
  • nix-darwin: The nix-darwin repository. It brings all modules to configure your macOSsystem using a declarative way.
  • home-manager: The home-manager repository. It brings all modules to configure youruser environment using a declarative way.

Configuring nix-darwin

After creating the flake.nix file, you can configure the nix-darwin module. You willneed to create a darwinConfigurations field on the outputs of your flake.nix file, andadd the hostname of your machine with the darwinSystem function.

{ # ...  outputs = inputs @ { self, nix-homebrew, home-manager ... }: let nixpkgsConfig = { config.allowUnfree = true; }; in { darwinConfigurations = let inherit (inputs.nix-darwin.lib) darwinSystem; in { machine = darwinSystem { system = "aarch64-darwin";  specialArgs = { inherit inputs; };  modules = [ ./hosts/mbp/configuration.nix inputs.home-manager.darwinModules.home-manager { nixpkgs = nixpkgsConfig;  home-manager.useGlobalPkgs = true; home-manager.useUserPackages = true; home-manager.users.noghartt = import ./home/home.nix; } ]; }; }; };}

In that case, what I’m doing is: creating a new configuration called machine on the darwinConfigurationssystems, and declaring some specific properties of that given system, they are:

  • The system of that machine is aarch64-darwin, which is the system of the new Apple SiliconMacs (MacBook Pro M1).
  • The specialArgs field is used to pass the inputs to the darwinSystem function. All modulesare functions that accept some arguments, the specialArgs field lets you pass new argumentsfor all these imported modules.
  • The modules field is used to define the modules that will be used to configure the system.In that case, I’m using the configuration.nix file to define my system configuration, thehome-manager module to configure the user environment, the homebrew.nix file to installall the packages that I want to install using Homebrew, and the home.nix file to configuremy user environment using home-manager.

Configuring my system

The configuration.nix file is used to define some system configurations related to myMacBook Pro, like user home dir, some extra options related to Nix binaries, and other system-related configurations that you want to declare. In my case, I wrote the following configuration.nix:

_: { services.nix-daemon.enable = true;  users.users.noghartt = { home = "/Users/noghartt"; };  nix.extraOptions = '' auto-optimise-store = true experimental-features = nix-command flakes extra-platforms = x86_64-darwin aarch64-darwin '';  homebrew = { enable = true;  casks = [ "discord" "visual-studio-code" ]; };}

Configuring the home-manager

The home.nix file is used to define the user environment configurations using the home-manager.In my case, I wrote just a simple home.nix file that installs some packages for me. It islike a configuration.nix file but for the user environment.

{ pkgs, ... }: { home.stateVersion = "23.11";  home.packages = with pkgs; [ htop curl coreutils jq ];  programs.zsh = { enable = true;  shellAliases = { ls = "ls --color"; }; };} 

With that configuration, I can install the initial packages that I want to use on mymachine using Nix, and gives me the powerful ability of reproducibility in a declarative way.

Building and activating the configuration

After creating all the files, you can build and activate the configuration using the following.You just need to run two specific commands to build and activate the configuration on yourmachine:

1. Building the configuration

nix build .#darwinConfigurations.machine.config.system

It will build the configuration of your machine targeting the darwinConfigurations.machineoutputs. Do not forget of changing the machine of the given name of your system configuration.

2. Activating the configuration

./result/sw/bin/darwin-rebuild switch --flake .

It will activate the configuration of your machine using the darwin-rebuild command. It willswitch the configuration of your machine to the new configuration that you have built.

Conclusion

In this blog post, I showed how to set up Nix on macOS using flakes, nix-darwin, and home-managerlike I do. I hope that this blog post can help you set up your configuration and let youuse Nix on your machine too.

I really love how the Nix package manager works, and I think that it is a great tool to useon your machine since it gives you a lot of power to manage your system and your user environment.You really should give it a try.

If you want to see my configuration, you can check it out on my repository,it’s all open source, feel free to use it as a base for your configuration if you want.

If you have any questions, feel free to ask me on Twitter or send me an email. I will be gladto help you with your doubts.

Resources

Set up Nix on macOS using flakes, nix-darwin and home-manager | Noghartt's garden (2024)
Top Articles
Latest Posts
Article information

Author: Lilliana Bartoletti

Last Updated:

Views: 6302

Rating: 4.2 / 5 (73 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Lilliana Bartoletti

Birthday: 1999-11-18

Address: 58866 Tricia Spurs, North Melvinberg, HI 91346-3774

Phone: +50616620367928

Job: Real-Estate Liaison

Hobby: Graffiti, Astronomy, Handball, Magic, Origami, Fashion, Foreign language learning

Introduction: My name is Lilliana Bartoletti, I am a adventurous, pleasant, shiny, beautiful, handsome, zealous, tasty person who loves writing and wants to share my knowledge and understanding with you.