This repository serves as a guide for setting up and managing my macOS system using Nix-Darwin, Nix Home Manager, and Homebrew. It is designed for personal reference but can also be useful to others interested in a similar setup.
How it works:
- The Nix package manager is used as the primary way to handle needed clitools, Languages, and apps.
- Nix-Darwin sets up the system based on the flake.nix and the correlating files in the nix-darwin directory.
- Nix-Home-Manager hooks into Nix-Darwin to handle the .config files and other .files in the home directory.
- Homebrew is used to install macOS apps and fonts. This is handled by Nix-Darwin's homebrew module, and a small
nix runbootstrap command installs Homebrew if it is missing.
Note
This is a first round at integrating nix-darwin, nix-home-manager, and homebrew. This is a work in progress and will be updated as I learn more. If you have any tips or know of a better way to do something, please let me know.
Warning
If you not looking to dive into the rabbit hole that is Nix, then this type of setup is not for you. It is a steep learning curve, but the benefits are worth it.
- Introduction
- Nix Language Overview
- Install Guide for Nix-Darwin
- Nix-Darwin Directory Structure
- Script/backup
- Converting Apple Key Codes (0x Format)
- Neovim Keybinds
- Resources - learning
The Nix language is a domain-specific, declarative, and functional language designed for defining derivations—precise descriptions of how existing files or inputs are used to generate new ones.
Tip
For a beginner-friendly introduction, visit the Introduction to Nix Language.
Language Features relevant to this setup:
Note
Will be updated as I learn more. Possibly some more examples.
| Example | Description |
|---|---|
"hello world" |
A basic string |
# Comment |
Simple comment |
true, false |
Boolean values |
[ 1 2 3 ] |
A list |
{ x = 1; y = 2; } |
An attribute set, nearly everything is a set |
"${pkgs.vim}/bin/vim" |
String interpolation |
{ inherit pkgs; } |
Inherit keyword |
import ./file.nix |
Import a Nix file |
{ ... } |
Ellipsis (ignored arguments) |
~/.config |
Home directory path |
./relative/path |
Relative path |
{ config, pkgs, ... }: { } |
Basic configuration |
Important
The Nix package manager is required to install nix-darwin. If you have not installed Nix, follow the instructions below.
-
Install the Nix package manager
Run the following command to install Nix:curl -sSf -L https://install.lix.systems/lix | sh -s -- install -
Clone the repository using a temporary Git installation
If Git is not installed, you can use a temporary version provided by Nix:nix-shell -p git --run "git clone https://github.com/MillerApps/dotfiles.git ~/dotfiles"
Note
This will:
- Temporarily use Git from Nix
- Clone your repository
- Create a
dotfilesdirectory in your home folder - Place all repository contents in
~/dotfiles
-
Use
justtemporarily to manage system commands
Ifjustis not installed, you can run it temporarily with Nix:nix-shell -p just
-
Bootstrap nix-darwin
nix-darwin for full details see, the installation instructions at the link. Use the flake section.
Note
This installs nix-darwin using the flake feature of nix. This is the recommended way to install nix-darwin.
This also assumes you cloned the repo to ~/dotfiles
Install xcode tools:
xcode-select --installInstall Homebrew once if it is not already present:
nix run "path:$HOME/dotfiles/nix-darwin#install-homebrew"-
Bootstrap nix-darwin
Use the Justfile target forbootstrap, or directly run:nix run nix-darwin --extra-experimental-features "nix-command flakes" -- switch --flake ~/dotfiles/nix-darwin#macbook
-
Rebuild and apply the configuration
Use the Justfile target forswitch, or directly run:darwin-rebuild switch --flake ~/dotfiles/nix-darwin#macbook
Note
These are the commands available in the Justfile. You can run them using just <command>.
Which will be available permanently after step 5, from within the dotfiles directory.
Click to view Justfile commands
switch: Switch to the current flake configurationbootstrap-homebrew: Install Homebrew with the flake bootstrap scriptbootstrap: Install Homebrew if needed, then bootstrap nix-darwinclean: Remove unused store entriesclean-all: Remove all unused store entries, including old generationsupdate: Update flake inputscheck: Verify configurationrollback: Rollback to the previous generationgenerations: Show system generations and available rollback targetsbuild: Build configuration without switching
The nix-darwin directory is structured as follows:
nix-darwin
├── flake.lock
├── flake.nix
├── home
│ ├── default.nix
│ └── tylermiller
│ ├── default.nix
│ ├── git.nix
│ ├── lazygit.nix
│ ├── neovim.nix
│ ├── spiceify.nix
│ ├── tmux.nix
│ └── zellij.nix
└── modules
├── common
│ ├── nix.nix
│ ├── packages.nix
│ ├── system.nix
│ ├── users.nix
│ └── zsh.nix
├── darwin
│ ├── homebrew.nix
│ └── macos.nix
├── pkgs
│ └── homebrew-bootstrap.nix
└── default.nixThe modules directory splits the config into modular files, which form the overall Nix-Darwin configuration.
default.nixis the container for all modules. This is automatically sourced by nix-darwin when importing./modulesinflake.nix.
- flake.nix
The primary configuration file for Nix Flakes. It defines inputs (dependencies like Nixpkgs, Home Manager, and Darwin modules) and outputs (system-wide and user-specific configurations). It serves as the entry point for building and managing the Nix-Darwin setup.
- flake.lock
A lock file that ensures the setup is reproducible by fixing dependencies to specific versions. This file is automatically generated and ensures consistent behavior across systems.
-
home/ A directory containing a
default.nixand atylermillerdirectory. Thedefault.nixfile is the entry point for building the user setup. The file acts as an entry point for Home Manager, separating the setup from the actual configurations. Thedefault.nixinside the tylermiller directory contains user-specific configurations, managed by Home Manager. It handles settings like shell preferences, environment variables, and dotfiles (my main use case). -
modules/
A collection of modular files that define specific aspects of the system or user configuration. Each file in this directory is dedicated to a particular functionality.
default.nix- This is the “main” file in the modules folder. When you import the folder, Nix automatically looks for default.nix first.
- It imports all your other modules (like homebrew.nix, macos.nix, etc.). Essentially, it says, “Combine all these configuration pieces together into one system configuration.”
homebrew.nix- Sets up Homebrew through nix‐darwin.
- Declares which Homebrew packages (taps, casks, and even Mac App Store apps) you want installed automatically.
- By listing them here, nix‐darwin ensures they’re always present, keeps them updated, and so on.
homebrew-bootstrap.nix- Exposes a
nix runcommand for installing Homebrew before the firstdarwin-rebuild switch. - Uses the official Homebrew installer and exits immediately when Homebrew is already present.
- Exposes a
macos.nix- Tweaks macOS‐specific settings, such as:
- Enabling sudo with Touch ID.
- Customizing the Dock (which apps are pinned, size, etc.).
- Finder preferences (showing hard drives on desktop, new window location, etc.).
- Trackpad settings.
- Think of it as your “macOS system preferences in Nix form.”
nix.nix- Adjusts how Nix itself behaves on your system.
- For instance, it might set your nixPath, turn on experimental features like flakes, etc.
packages.nix- Declares the system packages you want installed from the Nix package collection (nixpkgs).
- Lists things like command‐line tools (e.g., lazygit, bat, fzf, lua, etc.).
- If you add a package here, it will be part of your system profile.
system.nix- Contains some higher‐level nix‐darwin system config, such as a stateVersion or references to Git commit hashes (so you can track system changes).
- Not heavily used in every setup, but good for storing “top‐level” or version‐related settings.
users.nix- Defines user‐specific settings under users.users..
- For instance, it can set the home directory or other user details.
- In a more advanced setup, you could also manage user groups, shells, etc., but here it mainly shows where the home folder lives.
zsh.nix- Enables and configures Zsh as your login shell under nix‐darwin.
- Sets up additional Zsh features:
- Hooks to source Zsh plugins (e.g. zsh-autosuggestions, zsh-syntax-highlighting).
- Paths for frameworks like oh-my-zsh and theme engines like powerlevel10k.
flake.nixreferences./modulesand other configuration files to build the overall system and user setup.- The
modules/default.nixfile ensures that all relevant modules in the modules directory are included automatically. - This structure allows for a clear separation of concerns, making configurations easier to manage and extend.
Inside the script directory is an optional minimal backup script. Its only functionality is to perform a brew bundle dump and to make a backup of the current wallpaper if it has
changed.
Why brew bundle dump? Well simply in case I forgot to add the new app into homebrew.nix, this way I'm covered in case of a device failure as well.
Setup cron with the following:
crontab -eThen use the following:
# Runs every Monday, Wednesday, Friday, and Sunday at 1PM EST
0 13 * * 0,1,3,5 /Users/tylermiller/dotfiles/script/backup.zsh && curl -H ta:smiley -d "Backup complete" https://ntfy.<ntfy-url>/cronjob || curl -H ta:worried -d "Something went wrong" https://ntfy.<ntfy-url>/cronjob
# Convert hex to decimal using Bash arithmetic expansion
# Bash recognizes numbers prefixed with `16#` as base-16 (hexadecimal).
echo $((16#FFFF)) # 65535
echo $((16#0050)) # 80
# Convert decimal to hex using printf
# The %X formats the number as hexadecimal, and %04X ensures padding with zeros for 4 characters.
printf '0x%04X\\n' 65535 # 0xFFFF
printf '0x%04X\\n' 80 # 0x0050- The
16#prefix indicates a base-16 number. - The
$((...))syntax evaluates arithmetic expressions and converts the hexadecimal value into its decimal equivalent.
printfwith%Xformats the number as hexadecimal.%04Xensures the result is at least 4 characters wide, padding with zeros if necessary.- Adding
0xas a prefix makes it clear the output is in hexadecimal format.
Convert by multiplying each hex digit by its positional value (powers of 16).
- Write the number, separating each digit.
- Identify the positional value of each digit (16ⁿ from right to left).
- Multiply each digit by its positional value.
- Add the results together.
0 × 16³ (0 × 4096) = 0
0 × 16² (0 × 256) = 0
5 × 16¹ (5 × 16) = 80
0 × 16⁰ (0 × 1) = 0
= 80
F(15) × 16³ (15 × 4096) = 61,440
F(15) × 16² (15 × 256) = 3,840
F(15) × 16¹ (15 × 16) = 240
F(15) × 16⁰ (15 × 1) = 15
= 65,535
- Use a chart for hexadecimal digits (0-9, A-F):
Hex Digit Decimal Value 0 0 1 1 2 2 ... ... A 10 B 11 C 12 D 13 E 14 F 15
- Divide the decimal number by 16.
- Record the remainder (this will be the least significant digit).
- Repeat the division with the quotient until it equals 0.
- Reverse the remainders to get the hexadecimal result.
80 ÷ 16 = 5remainder0(least significant digit).5 ÷ 16 = 0remainder5.- Reverse the remainders:
50(hexadecimal).
Prefix: 65535 (0xFFFF) for all function keys
| Key | Decimal | Hex |
|---|---|---|
| F19 | 80 | 0x0050 |
| F20 | 90 | 0x005A |
| F21 | 91 | 0x005B |
| F22 | 92 | 0x005C |
| F23 | 93 | 0x005D |
| F24 | 94 | 0x005E |
The easier way would be to use this handy chart from jimratliff on GitHub:
Keyboard Mapping Reference
| Keyboard Label | Character | ASCII code (Parameter #1) | Mac Virtual Key Code (Parameter #2) | Layout dependence |
|---|---|---|---|---|
| 0 | 0 | 48 | 029 | ANSI-US |
| 1 | 1 | 49 | 018 | ANSI-US |
| 2 | 2 | 50 | 019 | ANSI-US |
| 3 | 3 | 51 | 020 | ANSI-US |
| 4 | 4 | 52 | 021 | ANSI-US |
| 5 | 5 | 53 | 023 | ANSI-US |
| 6 | 6 | 54 | 022 | ANSI-US |
| 7 | 7 | 55 | 026 | ANSI-US |
| 8 | 8 | 56 | 028 | ANSI-US |
| 9 | 9 | 57 | 025 | ANSI-US |
| A | a | 97 | 000 | ANSI-US |
| B | b | 98 | 011 | ANSI-US |
| C | c | 99 | 008 | ANSI-US |
| D | d | 100 | 002 | ANSI-US |
| E | e | 101 | 014 | ANSI-US |
| F | f | 102 | 003 | ANSI-US |
| G | g | 103 | 005 | ANSI-US |
| H | h | 104 | 004 | ANSI-US |
| I | i | 105 | 034 | ANSI-US |
| J | j | 106 | 038 | ANSI-US |
| K | k | 107 | 040 | ANSI-US |
| L | l | 108 | 037 | ANSI-US |
| M | m | 109 | 046 | ANSI-US |
| N | n | 110 | 045 | ANSI-US |
| O | o | 111 | 031 | ANSI-US |
| P | p | 112 | 035 | ANSI-US |
| Q | q | 113 | 012 | ANSI-US |
| R | r | 114 | 015 | ANSI-US |
| S | s | 115 | 001 | ANSI-US |
| T | t | 116 | 017 | ANSI-US |
| U | u | 117 | 032 | ANSI-US |
| V | v | 118 | 009 | ANSI-US |
| W | w | 119 | 013 | ANSI-US |
| X | x | 120 | 007 | ANSI-US |
| Y | y | 121 | 016 | ANSI-US |
| Z | z | 122 | 006 | ANSI-US |
| F1 | 65535 | 122 | Independent | |
| F2 | 65535 | 120 | Independent | |
| F3 | 65535 | 099 | Independent | |
| F4 | 65535 | 118 | Independent | |
| F5 | 65535 | 096 | Independent | |
| F6 | 65535 | 097 | Independent | |
| F7 | 65535 | 098 | Independent | |
| F8 | 65535 | 100 | Independent | |
| F9 | 65535 | 101 | Independent | |
| F10 | 65535 | 109 | Independent | |
| F11 | 65535 | 103 | Independent | |
| F12 | 65535 | 111 | Independent | |
| F13 | 65535 | 105 | Independent | |
| F14 | 65535 | 107 | Independent | |
| F15 | 65535 | 113 | Independent | |
| F16 | 65535 | 106 | Independent | |
| F17 | 65535 | 064 | Independent | |
| F18 | 65535 | 079 | Independent | |
| F19 | 65535 | 080 | Independent | |
| F20 | 65535 | 090 | Independent | |
| Keypad0 | 65535 | 082 | ANSI-US | |
| Keypad1 | 65535 | 083 | ANSI-US | |
| Keypad2 | 65535 | 084 | ANSI-US | |
| Keypad3 | 65535 | 085 | ANSI-US | |
| Keypad4 | 65535 | 086 | ANSI-US | |
| Keypad5 | 65535 | 087 | ANSI-US | |
| Keypad6 | 65535 | 088 | ANSI-US | |
| Keypad7 | 65535 | 089 | ANSI-US | |
| Keypad8 | 65535 | 091 | ANSI-US | |
| Keypad9 | 65535 | 092 | ANSI-US | |
| KeypadClear | 65535 | 071 | ANSI-US | |
| KeypadDecimal | 65535 | 065 | ANSI-US | |
| KeypadDivide | 65535 | 075 | ANSI-US | |
| KeypadEnter | 65535 | 076 | ANSI-US | |
| KeypadEquals | 65535 | 081 | ANSI-US | |
| KeypadMinus | 65535 | 078 | ANSI-US | |
| KeypadMultiply | 65535 | 067 | ANSI-US | |
| KeypadPlus | 65535 | 069 | ANSI-US | |
| Backslash | \ | 92 | 042 | ANSI-US |
| CapsLock | 65535 | 057 | Independent | |
| Comma | , | 44 | 043 | ANSI-US |
| Command | 65535 | 055 | Independent | |
| Control | 65535 | 059 | Independent | |
| Delete | 65535 | 051 | Independent | |
| DownArrow | 65535 | 125 | Independent | |
| End | 65535 | 119 | Independent | |
| Equal | = | 61 | 024 | ANSI-US |
| Escape | 27 | 053 | Independent | |
| ForwardDelete | 65535 | 117 | Independent | |
| Function | 65535 | 063 | Independent | |
| Grave | ` | 96 | 050 | ANSI-US |
| Help | 65535 | 114 | Independent | |
| Home | 65535 | 115 | Independent | |
| LeftArrow | 65535 | 123 | Independent | |
| LeftBracket | [ | 91 | 033 | ANSI-US |
| Minus | - | 45 | 027 | ANSI-US |
| Mute | 65535 | 074 | Independent | |
| Option | 65535 | 058 | Independent | |
| PageDown | 65535 | 121 | Independent | |
| PageUp | 65535 | 116 | Independent | |
| Period | . | 46 | 047 | ANSI-US |
| Quote | ' | 39 | 039 | ANSI-US |
| Return | 65535 | 036 | Independent | |
| RightArrow | 65535 | 124 | Independent | |
| RightBracket | ] | 93 | 030 | ANSI-US |
| RightCommand | 65535 | 054 | Independent | |
| RightControl | 65535 | 062 | Independent | |
| RightOption | 65535 | 061 | Independent | |
| RightShift | 65535 | 060 | Independent | |
| Semicolon | ; | 59 | 041 | ANSI-US |
| Shift | 65535 | 056 | Independent | |
| Slash | / | 47 | 044 | ANSI-US |
| Space | 32 | 049 | Independent | |
| Tab | 9 | 048 | Independent | |
| UpArrow | 65535 | 126 | Independent | |
| VolumeDown | 65535 | 073 | Independent | |
| VolumeUp | 65535 | 072 | Independent |
Or you can use the following method:
- Open Keyboard in System Preferences. system preferences > Keyboard (> Shortcuts)
- Then change settings for what you wish to find the symbolic hotkey IDs for.
- Use the following Sequence of commands to get all the information you need:
# 1. Dump current symbolic hotkey mappings
defaults read com.apple.symbolichotkeys > before.plist
# 2. Dump updated symbolic hotkey mappings
defaults read com.apple.symbolichotkeys > after.plist
# 3. Compare plists to identify the Symbolic Hotkey ID and its parameter values
diff before.plist after.plistThis process captures:
- Symbolic Hotkey ID (e.g., "163")
- Parameter array (keycode, modifiers)
- Type (e.g., "standard")
- Enabled state
- The diff will show the complete symbolic hotkey definition for the modified System Shortcut.
"com.apple.symbolichotkeys" = {
AppleSymbolicHotKeys = {
"163" = { # Notification Center
enabled = true;
value = {
parameters = [
65535 # Function key prefix (0xFFFF)
80 # Key code (F19 = 0x0050)
0 # No modifiers
];
type = "standard";
};
};
};
};<leader> is mapped to Space.
| Mode | Keybind | Action |
|---|---|---|
| Normal | <Esc> |
Clear search highlight |
| Normal | [d |
Go to previous diagnostic |
| Normal | ]d |
Go to next diagnostic |
| Normal | <leader>e |
Show diagnostic float |
| Normal | <leader>q |
Open diagnostic quickfix list |
| Normal | <C-h> |
Move focus to the left split |
| Normal | <C-l> |
Move focus to the right split |
| Normal | <C-j> |
Move focus to the lower split |
| Normal | <C-k> |
Move focus to the upper split |
| Normal | <A-h> |
Indent current line left |
| Normal | <A-j> |
Move current line down |
| Normal | <A-k> |
Move current line up |
| Normal | <A-l> |
Indent current line right |
| Visual | <A-h> |
Indent selected lines left |
| Visual | <A-j> |
Move selected lines down |
| Visual | <A-k> |
Move selected lines up |
| Visual | <A-l> |
Indent selected lines right |
| Insert | <A-h> |
Indent current line left and return to insert mode |
| Insert | <A-j> |
Move current line down and return to insert mode |
| Insert | <A-k> |
Move current line up and return to insert mode |
| Insert | <A-l> |
Indent current line right and return to insert mode |
| Normal | <C-s> |
Save file |
| Normal | <C-x> |
Save and quit |
| Normal | <C-q> |
Quit all |
| Insert | <C-j> |
Accept Copilot suggestion |
| Normal | <leader>l |
Open :Lazy |
| Mode | Keybind | Action |
|---|---|---|
| Normal | <C-n> |
Toggle NvimTree |
| Normal | <leader>E |
Focus NvimTree |
| Normal | - |
Open parent directory with Oil |
| Normal | <leader>- |
Open Yazi at the current file |
| Normal | <leader>cw |
Open Yazi in the current working directory |
| Normal | <C-y> |
Resume the last Yazi session |
| Mode | Keybind | Action |
|---|---|---|
| Normal | <A-,> |
Go to previous buffer |
| Normal | <A-.> |
Go to next buffer |
| Normal | <A-<> |
Move buffer left |
| Normal | <A->> |
Move buffer right |
| Normal | <A-1> |
Go to buffer 1 |
| Normal | <A-2> |
Go to buffer 2 |
| Normal | <A-3> |
Go to buffer 3 |
| Normal | <A-4> |
Go to buffer 4 |
| Normal | <A-5> |
Go to buffer 5 |
| Normal | <A-6> |
Go to buffer 6 |
| Normal | <A-7> |
Go to buffer 7 |
| Normal | <A-8> |
Go to buffer 8 |
| Normal | <A-9> |
Go to buffer 9 |
| Normal | <A-0> |
Go to last buffer |
| Normal | <A-p> |
Pin or unpin buffer |
| Normal | <A-c> |
Close buffer |
| Normal | <C-p> |
Pick buffer |
| Normal | <Space>bb |
Sort buffers by buffer number |
| Normal | <Space>bd |
Sort buffers by directory |
| Normal | <Space>bl |
Sort buffers by language |
| Normal | <Space>bw |
Sort buffers by window number |
| Mode | Keybind | Action |
|---|---|---|
| Normal | <leader>sh |
Search help tags |
| Normal | <leader>sk |
Search keymaps |
| Normal | <leader>sf |
Search files |
| Normal | <leader>ss |
Search Telescope pickers |
| Normal | <leader>sw |
Search current word |
| Normal | <leader>sg |
Live grep project |
| Normal | <leader>sd |
Search diagnostics |
| Normal | <leader>sr |
Resume last Telescope picker |
| Normal | <leader>s. |
Search recent files |
| Normal | <leader><leader> |
Find existing buffers |
| Normal | <leader>/ |
Fuzzy search current buffer |
| Normal | <leader>s/ |
Live grep open files |
| Normal | <leader>sn |
Search Neovim config files |
Inside Telescope pickers, use <C-/> in insert mode or ? in normal mode to show picker-local help.
These mappings are buffer-local and only become available after an LSP attaches.
| Mode | Keybind | Action |
|---|---|---|
| Normal | gd |
Go to definition |
| Normal | gr |
Go to references |
| Normal | gI |
Go to implementation |
| Normal | gD |
Go to declaration |
| Normal | K |
Show hover documentation |
| Normal | <leader>D |
Show type definitions |
| Normal | <leader>ds |
Search document symbols |
| Normal | <leader>ws |
Search workspace symbols |
| Normal | <leader>rn |
Rename symbol |
| Normal | <leader>ca |
Code action |
| Mode | Keybind | Action |
|---|---|---|
| Normal, Visual | <leader>gB |
Open Git browse |
| Normal | <leader>gb |
Show Git blame for current line |
| Normal | <leader>gf |
Open LazyGit file history |
| Normal | <leader>gg |
Open LazyGit |
| Normal | <leader>gl |
Open LazyGit log for cwd |
| Normal | <leader>un |
Dismiss all notifications |
| Normal, Terminal | <A-t> |
Toggle floating terminal |
| Normal, Terminal | ]] |
Jump to next reference |
| Normal, Terminal | [[ |
Jump to previous reference |
| Normal | <leader>dd |
Enable dim mode |
| Normal | <leader>do |
Disable dim mode |
| Mode | Keybind | Action |
|---|---|---|
| Normal | <leader>of |
Search Obsidian files |
| Normal | <leader>os |
Quick switch Obsidian note |
| Normal | <leader>on |
Create new Obsidian note |
| Normal | <leader>ol |
Follow Obsidian link |
| Normal | <leader>ob |
Show Obsidian backlinks |
| Normal | <leader>ot |
Browse Obsidian tags |
| Normal | <leader>p |
Paste image from system clipboard |
| Visual | <leader>fc |
Create a code image with Freeze |
| Mode | Keybind | Action |
|---|---|---|
| Normal | <leader>bt |
Toggle breakpoint |
| Normal | <leader>bc |
Continue debugger |
| Normal | <leader>bx |
Terminate debugger |
| Normal | <leader>bo |
Step over |
- Home Manager Options Reference - Comprehensive list of Home Manager options
- Nix Language Tutorial - Beginner-friendly introduction to the Nix language
- Nix Language Manual - Official Nix language documentation
- Nix Packages Search - Search for packages in Nixpkgs
- My Nixos - Has useful search for docs and packages
- Vimjoyer youtube - Great video series on nix and nixos
- Nix Glossary - Nix glossary of terms
- Nix Flakes - Nix Flakes docs
- Activate Your Preferences - Quick tip on activating preferences
- Apple keycodes chart - info - Apple keycodes
- Nix Witch - isabelroses (Nix Witch) blog on nix; very helpful if you reach out as well.
- Jake Hamilton - Past Live streams on nix and nixos
- Nix for Startups - Nix for Startups by Cam Pedersen

