- Used to run Nix Modules on macOS using the Darwin Unix-based core set of components
- Like a
/etc/nixos/configuration.nix
but for macOS - Since it will use the Nix Package Manager, just like NixOS, supports declarative reproductible system configurations
- Alternative or addition to Homebrew
This command will install the Nix Package Manager on your system. More information can be found here. When prompted, allow the installer to use root priviliges and to set up Nix as a Multi User.
$ sh <(curl -L https://nixos.org/nix/install)
If you just want to use the Nix Package Manager, great, you are done. You can install new packages using the command below. Available packages can be found here:
$ nix-env -iA nixpkgs.<package name>
$ nix-shell -p <package name>
If you would also like to configure these packages using their options, it’s recommended that you keep reading.
- Nix-Darwin can be installed by using the commands below:
$ nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer $ ./result/bin/darwin-installer
- The script above will not take care of files in
/etc
. If, after the installation, you get prompted that the script was not able to create a symlink in/etc
, it’s probably because the file already exists. In this case its best to# mv
. For example:
# mv /etc/bashrc /etc/bashrc.orig $ darwin-rebuild switch
- Packages: Don’t forget to check that the package is available for your system: x86_64-darwin (older MacBooks) or aarch64-darwin (Apple silicon).
- Options
$ man 5 configuration.nix
After installation a darwin-configuation.nix
file will be created in /Users/<user>/.nixpkgs
{ pkgs, ... }:
{
# Packages
environment.systemPackages = [
pkgs.vim
]
# Auto upgrade nix packages and the daemon service.
services.nix-daemon.enable = true;
nix.package = pkgs.nix;
}
$ darwin-rebuild switch
- In the past nix-darwin *.app files where places in
/Users/<user>/Applications
- Now nix-darwin should create a “Nix App” dir inside
/Applications
, so symlinking is no longer required. - They should all become available in the Launchpad.
- If your app is not available:
$ ls -la /nix/store | grep "<pkg name>" -- find correct path to package -- $ ln -s /nix/store/<correct path>/bin/<pkgname>.app /Applications/.
If you already have homebrew installed (which is a must), it’s possible to manage all packages in your configuration file.
homebrew = {
enable = true;
autoUpdate = true;
cleanup = "uninstall";
brews = [ "..." ];
casks = [ " " ];
taps = [ " " ];
...
}
But honestly, if it’s packaged in for Nix, use Nix;
system = {
defaults = {
NSGlobalDomain = { ... };
dock = { autohide = true; orientation = "bottom"; tilesize = int; };
finder = {};
trackpad = { Clicking = true; TrackpadRightClick = true; };
};
keyboard = { enableKeyMapping = true; };
};
environment = {
variables = {
EDITOR = "...";
VISUAL = "...";
};
};
- Remove undeclared packages, dependencies and symlinks:
$ sudo nix-collect-garbage -d
nix = {
gc = {
automatic = true;
interval.Day = 7; #Hours, minutes
options = "--delete-older-than 7d";
};
};
- It’s like configuration.nix, but for the user environment.
- Plenty more options to declare packages
As a user
- Add the channel:
$ nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
$ nix-channel --add https://github.com/nix-community/home-manager/archive/release-21.11.tar.gz home-manager
$ nix-channel --update
- Just to be sure, relog.
- If installation give NIX-PATH errors
$ sudo nix-collect-garbage -d
$ export NIX_PATH=$HOME/.nix-defexpr/channels:/nix/var/nix/profiles/per-user/root/channels${NIX_PATH:+:$NIX_PATH}
- Installation:
$ nix-shell ‘<home-manager>’ -A install
- Configuration file:
$ cd ~/.config/nixpkgs/home.nix
Add to configuration.nix
{
imports = [ <home-manager/nix-darwin> ];
users.users.<name> = {
name = "<name>";
home = "/User/<name>";
}
home-manager.users.<name> = { pkgs, …}: {
# declared packages. for example:
home.packages = [ pkgs.btop ];
};
}
- Home-Manager Options
$ man home-configuration.nix
home.packages = with pkgs; [
firefox
];
services.dunst = {
enable = true;
};
$ home-manager switch
- Flakes are an “upcoming feature” of the Nix package manager.
- Specify code dependencies declaratively (will be stored in flake.lock)
- For example: home-manager
- Rebuilding and updating whole system made easy
- Very useful tool to build your own config
- Multiple configs in one
- People with github dotfiles will feel right at home
Allowing experimental features such as flake to be installed
- If you already have a darwin-configuration.nix file. Rebuild the system with:
nix = { package = pkgs.nixFlakes; extraOptions = "experimental-features = nix-command flakes"; };
- If you are installing a flake without nix-darwin on your system
$ mkdir -p ~/.config/nix $ echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf
This command will generate a flake.nix and flake.lock file
- pick a location to store in your system
$ nix flake init
{
description = "A basic flake";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; #nixpkgs-22.05-darwin
darwin.url = "github:lnl7/nix-darwin/master";
darwin.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, darwin, nixpkgs }: {
darwinConfigurations."<host>" = darwin.lib.darwinSystem {
system = "x86_64-darwin";
modules = [ ./darwin-configuration.nix ];
};
};
}
attribute set of all the dependencies used in the flake
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
};
function of an argument that uses the inputs for reference
- Configure what you imported
- Can be pretty much anything: Packages / configurations / modules / etc…
This is only for those who don’t have nix-darwin installed and have an existing flake they want to install on a fresh system If this is not your situation, move on to rebuild
- For the first initial installation it recommended that your use
$ nix build
- The location of
/result
depends on what location you are building from. It’s maybe recommended that your build inside the flake.
$ cd <flake> $ nix build .#darwinConfiguration.<host>.system $ ./result/sw/bin/darwin-rebuild switch --flake .#<host>
- After the first installation, you don’t need to target
/darwin-rebuild
inside/result
$ darwin-rebuild
is now part of PATH and can be used from anywhere. Example:/HOME/<USER>/ $ darwin-rebuild switch ~/<flake>/#<host>
- If you already had nix-darwin installed, you can also use the command above.
- Remember that flakes use pure evaluation mode, home-manager will have to be set up from the flake and can not be imported and set up in
darwin-configuration.nix
- Remember that flakes use pure evaluation mode, home-manager will have to be set up from the flake and can not be imported and set up in
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
darwin.url = "github:lnl7/nix-darwin/master";
darwin.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, darwin … }: {
darwinConfigurations = {
<host> = darwin.lib.darwinSystem {
system = "x86_64-darwin";
modules = [ ./configuration.nix ];
};
#<second host> = darwin.lib.darwinSystem {
#system = "aarch64-darwin";
#modules = [ ./configuration.nix ];
#};
};
};
a “.(#)” will just build host found in location specify host with “<config path>#<host>” appended
$ darwin-rebuild build --flake .#
or build and automatically switch
$ darwin-rebuild switch --flake .#
{
inputs = {
#other inputs
home-manager = {
url = github:nix-community/home-manager;
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager, ... }:
let
#variables
system = "x86_64-darwin";
pkgs = nixpkgs.legacyPackages.system.${system};
in {
#other outputs
homeManagerConfigurations = {
<user> = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
extraSpecialArgs = { inherit <variables>; };
modules = [
</relative/path/to/home.nix>
{
home = {
username = “<user>”;
homeDirectory = “/Users/<user>”;
packages = [ pkgs.home-manager ];
stateVersion = "22.05";
};
}
];
};
};
};
}
{
inputs = {
#other inputs
home-manager = {
url = github:nix-community/home-manager;
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager, ... }:
let
#variables
system = "x86_64-darwin";
in {
darwinConfigurations = {
<user> = darwin.lib.darwinSystem {
inherit system;
modules = [
./configuration.nix
home-manager.darwinModules.home-manager {
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.users.<user> = {
imports = [ ./home.nix ];
};
}
];
};
};
};
}
This will build a directory with everything home-manager needs. An activation script is also located inside this dir
$ nix build .#homeManagerConfigurations.<user>.activationPackage
$ ./result/activate
Since home-manager is not installed, from now you can rebuild with:
$ home-manager switch --flake <config path>#<host>
Can be build with default rebuild command
$ sudo darwin-rebuild switch --flake .#<host>
This will update the flake.lock file
$ nix flake update
- Now rebuild and switch
$ nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A uninstaller $ ./result/bin/darwin-uninstaller
- Full guide
$ sudo rm -rf /nix /etc/nix ~/.nix*
- In
/etc
move all files with .backup-before.nix to original name (probably zshrc and bashrc) - Spotlight Search > Disk Utility > Unmount nix store > Delete volume
- reboot