General purpose Nix starter template for macOS or NixOS w/ step-by-step instructions
Nix
3,645
1,991 commits
updated Sep 27, 2026
Hey, you made it! Welcome. 🤓
Nix is a powerful package manager for Linux and Unix systems that ensures reproducible, declarative, and reliable software management.
This repository contains configuration for a general-purpose development environment that runs Nix on macOS, NixOS, or both simultaneously.
I use it daily on my 🧑🏻💻 Macbook Pro and an x86 PC in my home office. It also runs as a VM on your Mac. Many others have reported that it's working for them too.
Check out the step-by-step commands below to get started!
configuration.nix entry point, no Nix channels─ just flake.nixnix-darwin and nix-homebrewdisko, say goodbye to disk utilsagenix for SSH, PGP, syncthing, and other toolshome-manager module for seamless configuration (no extra clunky CLI steps)https://github.com/dustinlyons/nixos-config/assets/1292576/2168d482-6eea-4b51-adc1-2ef1291b6598
https://github.com/dustinlyons/nixos-config/assets/1292576/66001066-2bbf-4492-bc9e-60ea1abeb987
https://github.com/dustinlyons/nixos-config/assets/1292576/d96f59ce-f540-4f14-bc61-6126a74f9f52
https://github.com/dustinlyons/nixos-config/assets/1292576/fa54a87f-5971-41ee-98ce-09be048018b8
Installing Nix on macOS will create an entirely separate volume. It may exceed many gigabytes in size.
Some folks don't like this. If this is you, turn back now!
[!NOTE] Don't worry, you can always uninstall Nix later.
.
├── apps # Nix commands used to bootstrap and build configuration
├── hosts # Host-specific configuration
├── modules # macOS and nix-darwin, NixOS, and shared configuration
├── overlays # Drop an overlay file in this dir, and it runs. So far, mainly patches.
├── templates # Starter versions of this configuration
This configuration supports both Intel and Apple Silicon Macs.
xcode-select --install
sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install)
After installation, open a new terminal session to make the nix executable available in your $PATH. You'll need this in the steps ahead.
[!IMPORTANT]
If you recently updated to macOS 15 Sequoia and are getting
error: the user '_nixbld1' in the group 'nixbld' does not existwhen running Nix commands, refer to GitHub issue NixOS/nix#10892 for instructions to fix your installation without reinstalling.
flakes and nix-command aren't available by default. You'll need to enable them.
Add this line to your /etc/nix/nix.conf file
experimental-features = nix-command flakes
OR
Specify experimental features when using nix run below
nix --extra-experimental-features 'nix-command flakes' run .#<command>
Choose one of two options
Simplified version without secrets management
mkdir -p nixos-config && cd nixos-config && nix flake --extra-experimental-features 'nix-command flakes' init -t github:dustinlyons/nixos-config#starter
Full version with secrets management
mkdir -p nixos-config && cd nixos-config && nix flake --extra-experimental-features 'nix-command flakes' init -t github:dustinlyons/nixos-config#starter-with-secrets
find apps/$(uname -m | sed 's/arm64/aarch64/')-darwin -type f \( -name apply -o -name build -o -name build-switch -o -name clean -o -name create-keys -o -name copy-keys -o -name check-keys -o -name rollback \) -exec chmod +x {} \;
Run this Nix command to replace stub values with your system properties, username, full name, and email.
Your email is only used in the
gitconfiguration.
nix run .#apply
[!NOTE] If you're using a git repository, only files in the working tree will be copied to the Nix Store.
You must run
git add .first.
You can search for packages on the official NixOS website.
Review these files
Add anything from your existing ~/.zshrc, or just review the new configuration.
Review these files
If you are using the starter with secrets, there are a few additional steps.
In Github, create a private nix-secrets repository with at least one file (like a README). You'll enter this name during installation.
Before generating your first build, these keys must exist in your ~/.ssh directory. Don't worry, I provide a few commands to help you.
| Key Name | Platform | Description |
|---|---|---|
| id_ed25519 | macOS / NixOS | Github key with access to nix-secrets. Not copied to host, used only during bootstrap. |
| id_ed25519_agenix | macOS / NixOS | Primary key for encrypting and decrypting secrets. Copied over to host as id_ed25519. |
Run one of these commands:
This command auto-detects a USB drive connected to the current system.
Keys must be named
id_ed25519andid_ed25519_agenix.
nix run .#copy-keys
nix run .#create-keys
[!NOTE] If you choose this option, make sure to save the value of
id_ed25519.pubto Github.cat /Users/$USER/.ssh/id_ed25519.pub | pbcopy # Copy key to clipboard
If you're rolling your own, just check they are installed correctly.
nix run .#check-keys
Ensure the build works before deploying the configuration, run:
nix run .#build
[!NOTE] If you're using a git repository, only files in the working tree will be copied to the Nix Store.
You must run
git add .first.
[!WARNING] You may encounter
error: Unexpected files in /etc, aborting activationifnix-darwindetects it will overwrite an existing/etc/file. The error will list the files like this:The following files have unrecognized content and would be overwritten: /etc/nix/nix.conf /etc/bashrc Please check there is nothing critical in these files, rename them by adding .before-nix-darwin to the end, and then try again.Backup and move the files out of the way and/or edit your Nix configuration before continuing.
[!WARNING] You may encounter
error: Build user group has mismatching GID, aborting activationif you have already upgraded to Sequoia but had not prepared Nix before that. The error will list the files like this:error: Build user group has mismatching GID, aborting activation The default Nix build user group ID was changed from 30000 to 350. You are currently managing Nix build users with nix-darwin, but your nixbld group has GID 350, whereas we expected 30000.You will have to uninstall Nix, and install Nix again with
--nix-build-group-id 30000flag. See more here:
Finally, alter your system with this command:
nix run .#build-switch
[!CAUTION]
~/.zshrcwill be replaced with thezshconfiguration from this repository. Make sure this is what you want.
This configuration supports both x86_64 and aarch64 platforms.
Download and burn the minimal ISO image to a USB, or create a new VM with the ISO as base. Boot the installer.
If you're building a VM on an Apple Silicon Mac, choose 64-bit ARM.
Quick Links
If you are using the starter with secrets, there are a few additional steps.
In Github, create a private nix-secrets repository with at least one file (like a README). You'll enter this name during installation.
Before generating your first build, these keys must exist in your ~/.ssh directory. Don't worry, I provide a few commands to help you.
| Key Name | Platform | Description |
|---|---|---|
| id_ed25519 | macOS / NixOS | Github key with access to nix-secrets. Not copied to host, used only during bootstrap. |
| id_ed25519_agenix | macOS / NixOS | Primary key for encrypting and decrypting secrets. Copied over to host as id_ed25519. |
Run one of these commands:
This command auto-detects a USB drive connected to the current system.
Keys must be named
id_ed25519andid_ed25519_agenix.
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#copy-keys
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#create-keys
If you're rolling your own, just check they are installed correctly.
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#check-keys
[!IMPORTANT] For Nvidia cards, select the second option,
nomodeset, when booting the installer, or you will see a blank screen.
[!CAUTION] Running this will reformat your drive to the
ext4filesystem.
Simple
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#install
With secrets
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#install-with-secrets
On first boot at the login screen:
Ctrl-Alt-F2 (or Fn-Ctrl-Option-F2 if on a Mac) to move to a terminal sessionroot using the password created during installationpasswd <user>Ctrl-Alt-F7To create a new secret secret.age, first create a secrets.nix file at the root of your nix-secrets repository. Use this code:
[!NOTE]
secrets.nixis interpreted by the imperativeagenixcommands to pick the "right" keys for your secrets.Think of this file as the config file for
agenix. It's not part of your system configuration.
secrets.nix
let
user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
users = [ user1 ];
system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE";
systems = [ system1 ];
in
{
"secret.age".publicKeys = [ user1 system1 ];
}
Values for user1 should be your public key, or if you prefer to have keys attached to hosts, use the system1 declaration.
Now that we've configured agenix with our secrets.nix, it's time to create our first secret.
Run the command below.
EDITOR=vim nix run github:ryantm/agenix -- -e secret.age
This opens an editor to accept, encrypt, and write your secret to disk.
The command will look up the public key for secret.age, defined in your secrets.nix, and check for its private key in ~/.ssh/.
To override the SSH path, provide the
-iflag with a path to yourid_ed25519key.
Write your secret in the editor, save, and commit the file to your nix-secrets repo.
Now we have two files: secrets.nix and our secret.age.
Here's a more step-by-step example:
Let's say I wanted to create a new secret to hold my Github SSH key.
I would cd into my nix-secrets repo directory, verify the agenix configuration (named secrets.nix) exists, then run
EDITOR=vim nix run github:ryantm/agenix -- -e github-ssh-key.age
This would start a vim session.
I would enter insert mode :i, copy+paste the key, hit Esc and then type :w to save it, resulting in the creation of a new file, github-ssh-key.age.
Then, I would edit secrets.nix to include a line specifying the public key to use for my new secret. I specify a user key, but I could just as easily specify a host key.
secrets.nix
let
dustin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
users = [ dustin ];
systems = [ ];
in
{
"github-ssh-key.age".publicKeys = [ dustin ];
}
Finally, I'd commit all changes to the nix-secrets repository, go back to my nixos-config and run nix flake update to update the lock file.
The secret is now ready to use. Here's an example from my configuration. In the end, this creates a symlink to a decrypted file in the Nix Store that reflects my original file.
With Nix, changes to your system are made by
This is all wrapped up in the build-switch run command.
So, in general, the workflow for managing your environment will look like
nix run .#build-switchnix-darwin, home-manager, etc do their thingFor quickly trying a package without installing it, I usually run
nix shell nixpkgs#hello
where hello is the package name from nixpkgs.
This configuration has been tested and confirmed to work on the following platforms:
Have feedback or questions? Feel free to use the discussion forum.
Interested in contributing to this project? Here's how you can help:
Code Contributions: If you're interested in contributing code, please start by looking at open issues or feature requests. Fork the repository, make your changes, and submit a pull request. Make sure your code adheres to the existing style. For significant changes, consider opening an issue for discussion before starting work.
Reporting Bugs: If you encounter bugs or issues, please help by reporting them. Open a GitHub Issue and include as much detail as possible: what you were doing when the bug occurred, steps to reproduce the issue, and any relevant logs or error messages.
Reasons to jump into flakes and skip nix-env, Nix channels, etc
npm, cargo, poetry, composer, etc. Channels work more like traditional Linux distributions (like Ubuntu), which most devs don't know.nixpkgs version. Flakes lock each individual package to a version, which is more precise and makes it much easier to manage overall.| Component | Description |
|---|---|
| Window Manager | Xorg + bspwm |
| Terminal Emulator | alacritty |
| Bar | polybar |
| Application Launcher | rofi |
| Notification Daemon | dunst |
| Display Manager | lightdm |
| File Manager | thunar |
| Text Editor | emacs daemon mode |
| Media Player | cider |
| Image Viewer | feh |
| Screenshot Software | flameshot |
This project is released under the BSD-3-Clause license.
If this project has been useful, consider supporting it.
I maintain this configuration in my spare time. I also build software for music and performing arts schools to manage scheduling, billing, and student records—if you know a teacher or studio owner, feel free to share Conductly.
"All we have to decide is what to do with the time that is given us." - J.R.R. Tolkien
(top 24 of 91)
2,201 followers · starred Dec 2024
175 followers · starred Apr 2026
70 followers · starred Oct 2024
1,958 followers · starred Jun 2025
General purpose Nix starter template for macOS or NixOS w/ step-by-step instructions
Nix
3,645
1,991 commits
updated Sep 27, 2026
Hey, you made it! Welcome. 🤓
Nix is a powerful package manager for Linux and Unix systems that ensures reproducible, declarative, and reliable software management.
This repository contains configuration for a general-purpose development environment that runs Nix on macOS, NixOS, or both simultaneously.
I use it daily on my 🧑🏻💻 Macbook Pro and an x86 PC in my home office. It also runs as a VM on your Mac. Many others have reported that it's working for them too.
Check out the step-by-step commands below to get started!
configuration.nix entry point, no Nix channels─ just flake.nixnix-darwin and nix-homebrewdisko, say goodbye to disk utilsagenix for SSH, PGP, syncthing, and other toolshome-manager module for seamless configuration (no extra clunky CLI steps)https://github.com/dustinlyons/nixos-config/assets/1292576/2168d482-6eea-4b51-adc1-2ef1291b6598
https://github.com/dustinlyons/nixos-config/assets/1292576/66001066-2bbf-4492-bc9e-60ea1abeb987
https://github.com/dustinlyons/nixos-config/assets/1292576/d96f59ce-f540-4f14-bc61-6126a74f9f52
https://github.com/dustinlyons/nixos-config/assets/1292576/fa54a87f-5971-41ee-98ce-09be048018b8
Installing Nix on macOS will create an entirely separate volume. It may exceed many gigabytes in size.
Some folks don't like this. If this is you, turn back now!
[!NOTE] Don't worry, you can always uninstall Nix later.
.
├── apps # Nix commands used to bootstrap and build configuration
├── hosts # Host-specific configuration
├── modules # macOS and nix-darwin, NixOS, and shared configuration
├── overlays # Drop an overlay file in this dir, and it runs. So far, mainly patches.
├── templates # Starter versions of this configuration
This configuration supports both Intel and Apple Silicon Macs.
xcode-select --install
sh <(curl --proto '=https' --tlsv1.2 -L https://nixos.org/nix/install)
After installation, open a new terminal session to make the nix executable available in your $PATH. You'll need this in the steps ahead.
[!IMPORTANT]
If you recently updated to macOS 15 Sequoia and are getting
error: the user '_nixbld1' in the group 'nixbld' does not existwhen running Nix commands, refer to GitHub issue NixOS/nix#10892 for instructions to fix your installation without reinstalling.
flakes and nix-command aren't available by default. You'll need to enable them.
Add this line to your /etc/nix/nix.conf file
experimental-features = nix-command flakes
OR
Specify experimental features when using nix run below
nix --extra-experimental-features 'nix-command flakes' run .#<command>
Choose one of two options
Simplified version without secrets management
mkdir -p nixos-config && cd nixos-config && nix flake --extra-experimental-features 'nix-command flakes' init -t github:dustinlyons/nixos-config#starter
Full version with secrets management
mkdir -p nixos-config && cd nixos-config && nix flake --extra-experimental-features 'nix-command flakes' init -t github:dustinlyons/nixos-config#starter-with-secrets
find apps/$(uname -m | sed 's/arm64/aarch64/')-darwin -type f \( -name apply -o -name build -o -name build-switch -o -name clean -o -name create-keys -o -name copy-keys -o -name check-keys -o -name rollback \) -exec chmod +x {} \;
Run this Nix command to replace stub values with your system properties, username, full name, and email.
Your email is only used in the
gitconfiguration.
nix run .#apply
[!NOTE] If you're using a git repository, only files in the working tree will be copied to the Nix Store.
You must run
git add .first.
You can search for packages on the official NixOS website.
Review these files
Add anything from your existing ~/.zshrc, or just review the new configuration.
Review these files
If you are using the starter with secrets, there are a few additional steps.
In Github, create a private nix-secrets repository with at least one file (like a README). You'll enter this name during installation.
Before generating your first build, these keys must exist in your ~/.ssh directory. Don't worry, I provide a few commands to help you.
| Key Name | Platform | Description |
|---|---|---|
| id_ed25519 | macOS / NixOS | Github key with access to nix-secrets. Not copied to host, used only during bootstrap. |
| id_ed25519_agenix | macOS / NixOS | Primary key for encrypting and decrypting secrets. Copied over to host as id_ed25519. |
Run one of these commands:
This command auto-detects a USB drive connected to the current system.
Keys must be named
id_ed25519andid_ed25519_agenix.
nix run .#copy-keys
nix run .#create-keys
[!NOTE] If you choose this option, make sure to save the value of
id_ed25519.pubto Github.cat /Users/$USER/.ssh/id_ed25519.pub | pbcopy # Copy key to clipboard
If you're rolling your own, just check they are installed correctly.
nix run .#check-keys
Ensure the build works before deploying the configuration, run:
nix run .#build
[!NOTE] If you're using a git repository, only files in the working tree will be copied to the Nix Store.
You must run
git add .first.
[!WARNING] You may encounter
error: Unexpected files in /etc, aborting activationifnix-darwindetects it will overwrite an existing/etc/file. The error will list the files like this:The following files have unrecognized content and would be overwritten: /etc/nix/nix.conf /etc/bashrc Please check there is nothing critical in these files, rename them by adding .before-nix-darwin to the end, and then try again.Backup and move the files out of the way and/or edit your Nix configuration before continuing.
[!WARNING] You may encounter
error: Build user group has mismatching GID, aborting activationif you have already upgraded to Sequoia but had not prepared Nix before that. The error will list the files like this:error: Build user group has mismatching GID, aborting activation The default Nix build user group ID was changed from 30000 to 350. You are currently managing Nix build users with nix-darwin, but your nixbld group has GID 350, whereas we expected 30000.You will have to uninstall Nix, and install Nix again with
--nix-build-group-id 30000flag. See more here:
Finally, alter your system with this command:
nix run .#build-switch
[!CAUTION]
~/.zshrcwill be replaced with thezshconfiguration from this repository. Make sure this is what you want.
This configuration supports both x86_64 and aarch64 platforms.
Download and burn the minimal ISO image to a USB, or create a new VM with the ISO as base. Boot the installer.
If you're building a VM on an Apple Silicon Mac, choose 64-bit ARM.
Quick Links
If you are using the starter with secrets, there are a few additional steps.
In Github, create a private nix-secrets repository with at least one file (like a README). You'll enter this name during installation.
Before generating your first build, these keys must exist in your ~/.ssh directory. Don't worry, I provide a few commands to help you.
| Key Name | Platform | Description |
|---|---|---|
| id_ed25519 | macOS / NixOS | Github key with access to nix-secrets. Not copied to host, used only during bootstrap. |
| id_ed25519_agenix | macOS / NixOS | Primary key for encrypting and decrypting secrets. Copied over to host as id_ed25519. |
Run one of these commands:
This command auto-detects a USB drive connected to the current system.
Keys must be named
id_ed25519andid_ed25519_agenix.
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#copy-keys
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#create-keys
If you're rolling your own, just check they are installed correctly.
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#check-keys
[!IMPORTANT] For Nvidia cards, select the second option,
nomodeset, when booting the installer, or you will see a blank screen.
[!CAUTION] Running this will reformat your drive to the
ext4filesystem.
Simple
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#install
With secrets
sudo nix run --extra-experimental-features 'nix-command flakes' github:dustinlyons/nixos-config#install-with-secrets
On first boot at the login screen:
Ctrl-Alt-F2 (or Fn-Ctrl-Option-F2 if on a Mac) to move to a terminal sessionroot using the password created during installationpasswd <user>Ctrl-Alt-F7To create a new secret secret.age, first create a secrets.nix file at the root of your nix-secrets repository. Use this code:
[!NOTE]
secrets.nixis interpreted by the imperativeagenixcommands to pick the "right" keys for your secrets.Think of this file as the config file for
agenix. It's not part of your system configuration.
secrets.nix
let
user1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
users = [ user1 ];
system1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPJDyIr/FSz1cJdcoW69R+NrWzwGK/+3gJpqD1t8L2zE";
systems = [ system1 ];
in
{
"secret.age".publicKeys = [ user1 system1 ];
}
Values for user1 should be your public key, or if you prefer to have keys attached to hosts, use the system1 declaration.
Now that we've configured agenix with our secrets.nix, it's time to create our first secret.
Run the command below.
EDITOR=vim nix run github:ryantm/agenix -- -e secret.age
This opens an editor to accept, encrypt, and write your secret to disk.
The command will look up the public key for secret.age, defined in your secrets.nix, and check for its private key in ~/.ssh/.
To override the SSH path, provide the
-iflag with a path to yourid_ed25519key.
Write your secret in the editor, save, and commit the file to your nix-secrets repo.
Now we have two files: secrets.nix and our secret.age.
Here's a more step-by-step example:
Let's say I wanted to create a new secret to hold my Github SSH key.
I would cd into my nix-secrets repo directory, verify the agenix configuration (named secrets.nix) exists, then run
EDITOR=vim nix run github:ryantm/agenix -- -e github-ssh-key.age
This would start a vim session.
I would enter insert mode :i, copy+paste the key, hit Esc and then type :w to save it, resulting in the creation of a new file, github-ssh-key.age.
Then, I would edit secrets.nix to include a line specifying the public key to use for my new secret. I specify a user key, but I could just as easily specify a host key.
secrets.nix
let
dustin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0idNvgGiucWgup/mP78zyC23uFjYq0evcWdjGQUaBH";
users = [ dustin ];
systems = [ ];
in
{
"github-ssh-key.age".publicKeys = [ dustin ];
}
Finally, I'd commit all changes to the nix-secrets repository, go back to my nixos-config and run nix flake update to update the lock file.
The secret is now ready to use. Here's an example from my configuration. In the end, this creates a symlink to a decrypted file in the Nix Store that reflects my original file.
With Nix, changes to your system are made by
This is all wrapped up in the build-switch run command.
So, in general, the workflow for managing your environment will look like
nix run .#build-switchnix-darwin, home-manager, etc do their thingFor quickly trying a package without installing it, I usually run
nix shell nixpkgs#hello
where hello is the package name from nixpkgs.
This configuration has been tested and confirmed to work on the following platforms:
Have feedback or questions? Feel free to use the discussion forum.
Interested in contributing to this project? Here's how you can help:
Code Contributions: If you're interested in contributing code, please start by looking at open issues or feature requests. Fork the repository, make your changes, and submit a pull request. Make sure your code adheres to the existing style. For significant changes, consider opening an issue for discussion before starting work.
Reporting Bugs: If you encounter bugs or issues, please help by reporting them. Open a GitHub Issue and include as much detail as possible: what you were doing when the bug occurred, steps to reproduce the issue, and any relevant logs or error messages.
Reasons to jump into flakes and skip nix-env, Nix channels, etc
npm, cargo, poetry, composer, etc. Channels work more like traditional Linux distributions (like Ubuntu), which most devs don't know.nixpkgs version. Flakes lock each individual package to a version, which is more precise and makes it much easier to manage overall.| Component | Description |
|---|---|
| Window Manager | Xorg + bspwm |
| Terminal Emulator | alacritty |
| Bar | polybar |
| Application Launcher | rofi |
| Notification Daemon | dunst |
| Display Manager | lightdm |
| File Manager | thunar |
| Text Editor | emacs daemon mode |
| Media Player | cider |
| Image Viewer | feh |
| Screenshot Software | flameshot |
This project is released under the BSD-3-Clause license.
If this project has been useful, consider supporting it.
I maintain this configuration in my spare time. I also build software for music and performing arts schools to manage scheduling, billing, and student records—if you know a teacher or studio owner, feel free to share Conductly.
"All we have to decide is what to do with the time that is given us." - J.R.R. Tolkien
(top 24 of 91)
2,201 followers · starred Dec 2024
175 followers · starred Apr 2026
70 followers · starred Oct 2024
1,958 followers · starred Jun 2025