Setting up a new Mac 2023 edition

I've just got an M2 Mac Studio and I'm going through my preferred way of setting up a new machine. I'm gonna document it somewhat more thoroughly than I've previously done. This is mainly just documentation for myself for next time around, but maybe someone else might find some inspiration from it too?

Main points for anyone else reading - I'm very sceptical of any non-FOSS product lock-in. I'm also very scared of state on client machines. In a perfect world I want to feel safe knowing I can drop my machine in the ocean, buy a new one, import  a single GPG key and setup a new machine with a click. Time Machine is cheating. My world is not that perfect yet, but I'm taking baby steps. I've read posts

Basically I try to achieve this by having all my work in git repos, Dropbox or Google Drive on a use-case basis. Machine "state" I'm trying to keep low by using Nix, home-manager and nix-darwin. I'm meticulous about not installing any globals if I can avoid it. In my world that's anything like Java, Haskell, Node or Python versions. Nix shells are perfect for this and I've replaced all uses of tool-specific "version managers" with nix at this point. Passwords with GnuPass But first things first, I need a keyboard and mouse!

Keyboard and mouse

I have a Logitech Mx Master 3 and a Ergo K860 keyboard. Currently I'm using these on channel 1 towards my Hackintosh and channel 2 is Bluetooth against my M1 Air laptop. Just plugging in a dongle and trying to pair during initial setup of the new Mac Studio didn't work because it wasn't already paired to this previously unused dongle. I have extra dongles and these are stateful so therefore I could pair the devices on the dongle using the devices channel 3 using Logitech Unifying software on my laptop first
And then I could move the dongle over to my new Mac Studio and it just works. Channel 2 for the devices is still paired to the same laptop over Bluetooth and channel 1 to the Hackintosh's dongle. Great!

Going through Apples init

I just have to click through this, I don't think there's anything I can do to get around that that's worth exploring.

Migration assistant? - "Not now" or rather no way, never.

Sign in with AppleID - yes sure, I unfortunately need this still. I would like not too, but I have some paid AppleStore software I still need.

And here are the first glitches in my not-so-perfect world! I have yet to install keyboard customizer Karabiner-Elements that I need to use my keyboard. Took a while to even find the @ sign for my Apple account.

Next up - password for Apple account. That's of course in my password manager GnuPass which I have no access to yet on this new machine - I first need to go get it via nix plus checking out a git repo with the gpg keys, but more on that later. So here I just gotta use phone or machine on the side - currently writing this on M1 Air on the side - and just copy it down manually. This is the most painful part of a new machine. For me this means

pass apple/appleid/password 

in Terminal and then typing a superlong password on the new machine with weird keyboard. Apple doesn't make this easier with no way to view password input as far as I know. Wish me luck!

Ok, back! Took a while, because Apple had defaulted to some keyboard layout "ABC" instead of "Swedish" so some special characters went awry. Never had that problem before?

At this point I had to allow the usage of my AppleId on a push to this machine.

Terms and conditions - tldr

Setting up new account - "Allow my Apple ID to reset this password" - whooah! no way - you mean some cloud service could connect to some running daemon on my machine that would be able to change my unix passwords? Sounds waaay too scary to me. My machine sudo password is something I'm actually reusing and I will probably know it by heart and fingers until far into the mists of dementia.

iCloud - no, I don't want iCloud, why are you "setting up account"? "setup later". More likely never.

Location service - this is a desktop machine that will hopefully stay on my desk for long so I don't see the point in giving Apple access to my location. Disable all analytics too. Dark theme. Some keyboard thing I'll just need to press some button. Will fix later with Karabiner.

Ok, I'm in! MacOs! (I can't write OSX anymore can I?)

Hey Terminal

Ok, let's find a terminal! I guess that means the actual app "Terminal" before I setup nix to get me some kitty

No terminal on Dock but I have this! CMD-space, type "term…" and there it is!

Yes, zsh nowadays on macos. Shize, everything is hard at this point. I want my dotfiles, Kitty and fish!

At this point I need my GPG keys to get access to my git repos containing both passwords and dotfiles. I think I have a chicken and egg problem too. I would like to get git without Apple developer tools, is that possible?

Typing git gives me a popup for installing Developer Tools CLI. Can I possibly start with nix and a nix-shell with git to avoid this? I'll try!

I'll hit and just copy the sh/curl install. I trust it! I'm really happy at this point because last time this was super hard on Apple silicon, but now I think this will be smooth riding.

Yes, nix is installed, yey!

At this point I think I can actually do grown-up things using nix-env.


But I need my keys too… I think its reasonable to do this with Airdrop?

On other machine, I'll export my GPG keys using

gpg -a --export-secret-key > secret-all.asc

and then I'll Airdrop this to the new machine. There I'll import them in the nix-shell:

nix-shell -p gnupg
gpg --import ~/Downloads/secret-all.asc

Awesome, now let's hook GPG up with SSH so that I can retrieve my private git repos. For this I need to add GPG as my means to authenticate SSH.

gpg -K --with-keygrip

This gets me my keygrips. I'll paste the A subkey I have into ~/.gnupg/sshcontrol and also enable ssh support:

echo "enable-ssh-support" > ~/.gnupg/gpg-agent.conf
echo MY_KEY_GRIP_GOES_HERE > ~/.gnupg/sshcontrol
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)

That's it for showing this computer is me. I can now ssh into any of my machines and checkout my git repos. Let's start with getting my dotfiles:

nix-shell -p gnupg git
git clone
cd dotfiles

I'm using Gnu Stow with my dotfiles ( so I need to add this to my nix-shell and stow all my settings.

I have instructions in my dotfiles repo how to manage it, but most importantly I have stow folders for git, fish, nix and kitty that I need to softlink:

nix-shell -p gnugp git stow
stow -t ~ git
stow -t ~ fish
stow -t ~ kitty
stow -t ~ nix

I replaced the usage of a bare git repo, something like for dotfiles with stow. I think this is a lot more clear and manageable. The linking just works and no risk of doing something crazy. I sleep better at night. It's just a normal repo.

At this point I should be able to put a nail in the coffin with home-manager and nix-darwin to get all my stuffz. My nix stow contains a darwin-configuration.nix and a home.nix - the latter being anything non-apple specific that I also use on a Linux machine. But on a Mac I'm gonna bootstrap via nix-darwin.

# Official install instructions:
nix-build -A installer

# The installer puts a file in ~/.nixpkgs but I will then update the location to my stowed one that is under ~/.config/nixpkgs  - that's actually suggested in the first one.

# The installer puts stuff in zsh and bash files. This is a bit messy, but to get darwin-rebuild into my path I'll just exit out of everything and start a new terminal (zsh)

# I also need home-manager using this approach

nix-channel --add home-manager
nix-channel --update

# I need to manually install homebrew, but it will be used only from nix-darwin
/bin/bash -c "$(curl -fsSL"

# Then get all the stuffz:
ln -s ~/.config/nixpkgs/darwin-configuration.nix ~/.nixpkgs/darwin-configuration.nix
darwin-rebuild switch	


I want to store all my config in the dotfiles repo while keeping the ability to have machine specific configuration too so I'll touch these up for this machine. I haven't found a way to do selective imports other than having git-ignored includes. On the top of my main kitty.conf I have:

globinclude local-pre/**/*.conf

and at the bottom the same without "-pre". So on a new machine I need to add a few files, I'll just base this machine of this machine for now:

cp ~/.config/kitty/viktor.air-pre.conf studio-pre.conf
cp ~/.config/kitty/viktor.air.conf studio.conf
echo "include ../studio-pre.conf" > ~/.config/kitty/local/studio-pre.conf
echo "include ../studio.conf" > ~/.config/kitty/local/studio.conf

With previous cask installs I can now start kitty as a UI app and it will use fish as the login shell with all my settings.

Password store

GnuPass with a git repo. I'll just:

git clone ~/.password-store

Since GPG is all setup already I can now use my passwords. I have an alias in fish to strip trailing newline and stick in clipboard:

function cppass --wraps pass
  pass $argv | tr -d '\n' | pbcopy

And then of course browser integration plus Android using the same store and GPG:

Might merit a separate blog post.

I think that's it for now, I'm pretty much up and running.


  • I need to cleanup my private dotfiles repo to make sure I at no time had any sercrets there and I'll post a link to that.
  • I also want to use nix flakes..
  • I'll continue to explore what can be done to ease further with Macos settings from nix-darwin.  I currently only have Dock settings, but I think it's possible to find most settings, but the docs are outdated and Apple have moved stuff around. Some inspiration here but it seems I need to investigate what works and what not in latest Macos.
  # Iterate testing
  #  defaults delete or nix-darwin rebuild
  # killall Dock
  # if it doesn't come back - something wrong with settings

  system.defaults.CustomUserPreferences = {
    # defaults domains - to list domains
    # defaults read _domain_ to show settings
    # Then stick stuff here:
    "" = {
      autohide = 1;
      tilesize = 20;