my hard work / by these words guarded / please steal. (c) JoseCanHelp
Declarative dotfiles for macOS and WSL2, built with Nix, nix-darwin, and home-manager. The flake manages packages, applications, macOS settings, shell, editor, and background jobs.
Borrowing is encouraged. If you take something from here, a link back is appreciated.
Install Determinate Nix.
Clone this repository to
~/dotfiles. That path is part of the linked-file configuration.git clone git@github.com:josecanhelp/dotfiles.git ~/dotfilesAdd a host block to
flake.nixif the machine is not already listed.Apply the configuration:
sudo darwin-rebuild switch --flake ~/dotfiles#REM-JoseS-MBP1Create
~/.secretsif needed. It is sourced by zsh and is not tracked.
There is no install script, manual brew bundle step, or plugin manager to
bootstrap.
Add one block to darwinConfigurations in flake.nix:
"Joses-Mac-mini"=mkHost{hostname="Joses-Mac-mini";user="jose";};The attribute name, hostname, and the name passed to darwin-rebuild must
match. For an Intel Mac, also set system = "x86_64-darwin".
Machine-specific changes belong in a separate module passed through
extraModules; shared settings stay in the existing modules.
The Linux target is standalone home-manager. It manages $HOME, not the
machine, and does not evaluate the macOS nix-darwin or Homebrew configuration.
First activation:
nix run home-manager/master -- switch -b bak --flake ~/dotfiles#jose@RockemSockemLater activations:
home-manager switch --flake ~/dotfiles#jose@RockemSockemThe Linux output imports the portable modules under nix/home/shared/ and its
own package and shell settings from nix/home/linux/default.nix.
Use the layer that owns the thing being configured:
| Layer | Scope | Main files |
|---|---|---|
| Flake | Inputs and package versions | flake.nix, flake.lock |
| nix-darwin | The macOS machine | nix/configuration.nix, nix/packages.nix |
| nix-homebrew | Homebrew installation and trust | flake.nix, nix/configuration.nix |
| home-manager | User files and user launchd agents | nix/home/ |
| Linked source files | Runtime-editable configurations | hammerspoon/, karabiner/, amethyst/, bin/ |
As a rule, use nix-darwin for machine-wide settings and home-manager for files
in the home directory. Homebrew declarations are macOS-only: brews, casks,
and masApps live in the homebrew block in nix/configuration.nix.
| Change | File |
|---|---|
| Shell aliases, prompt, or environment | nix/home/shared/shell.nix |
| Git configuration | nix/home/shared/git.nix |
| tmux configuration | nix/home/shared/tmux.nix |
| Neovim packages or configuration | nix/home/shared/nvim.nix, nvim/init.lua |
| Change | File |
|---|---|
| CLI packages | nix/packages.nix |
| GUI apps, brew formulas, or App Store apps | nix/configuration.nix |
| macOS defaults, fonts, or activation scripts | nix/configuration.nix |
| Linked application configurations | nix/home/darwin/default.nix and its modules |
| Login or background jobs | nix/home/darwin/ |
| Change | File |
|---|---|
| CLI packages and Linux-only settings | nix/home/linux/default.nix |
Adding a CLI tool to both machines requires two edits because the Mac uses
environment.systemPackages and Linux uses home.packages. The lists are
intentionally different.
Most configuration is generated into the Nix store and linked into place. Edit the Nix module and rebuild it.
These files are linked directly from the checkout so their owning tools can edit or reload them without a rebuild:
| Tool | Source |
|---|---|
| Hammerspoon | hammerspoon/ |
| Karabiner and Goku input | karabiner/karabiner.edn |
| Amethyst | amethyst/amethyst.yml |
| Claude notification hook | claude/notify.sh |
| Claude status line | claude/statusline.sh |
| Personal scripts | bin/ |
| Login suppression | hushlogin |
Two files are sourced from the checkout rather than linked: the zsh functions
file and tmux/tmuxline. The supported checkout path is ~/dotfiles.
Build the macOS system without activating it:
nix build .#darwinConfigurations.REM-JoseS-MBP1.system --no-link --print-out-pathsCheck declared binaries, links, and launchd agents:
nix/verify.sh all
nix/verify.sh links
nix/verify.sh agentsThe Linux output can be evaluated from the Mac, but not cross-built without a Linux builder:
nix eval'.#homeConfigurations."jose@RockemSockem".config.home.packages' --apply 'builtins.length'Nix reads repository files as flake inputs, so add new files to git before building them.
- Adding and removing things is the practical cookbook for packages, modules, Homebrew, apps, extensions, settings, and background jobs.
- Nix conventions explains module choices, portable versus platform-specific configuration, ordering, and verification.
- Keyboard workflow explains the Karabiner and Hammerspoon layers.
- Reproducibility review tracks remaining non-declarative state and known gaps.
- Historical audit records the original machine audit and its resolved findings.
Neovim is a terminal editor managed through nix/home/shared/nvim.nix and
nvim/init.lua. tmux uses plugins from nixpkgs rather than tpm. The terminal
font is FiraCode Nerd Font Mono, declared in nix/configuration.nix.
Karabiner reads the generated karabiner.json, which is compiled from
karabiner/karabiner.edn by the declared Goku launchd agent. Hammerspoon owns
the higher-level, application-specific keyboard actions.
