Filip's Blog

Home

A little bit of Nix-based fun

Published

I discovered Nix quite a while ago: I remember it was in 2022 when I saw @ghuntley praise it publicly and at the time, I didn’t pay too much attention to it or to what it even was, since I was scared of bringing more complexity into my already hacky and complicated setups, in which I juggled between using Windows and my new MacBook, which I was still getting accustomed to (as one does being a lifelong victim of Microsoft’s OS dominance over the PC market).

2022 was also the year dotfiles became a first-class citizen in Gitpod and I wanted to try it out so bad: I had so many ideas what to do with them ranging from funny login messages through setting up gpg commit signing. Unfortunately, none of my original intentions with dotfiles went through: in the end, I was just frustrated that I couldn’t easily debug my setup and gave up (also since they weren’t crucial for my day-to-day anyway).

Fast forward to last October, when I saw nix mentioned again in a video in my YouTube recommended. All of a sudden, the whole appeal of Nix clicked: I love my local macOS setup, but I’ve always feared messing something up and not being able to revert it, like I’m used to with all my other work. Now, after watching that amazing video I had to at least give it a shot: after not even an hour, I had a working nix-darwin setup with all my homebrew casks and brews migrated to a single nix flake, which I was able to manage all from with my text editor - wow! No more brew installs and uninstalls, just change a text file, run a command, and this magic little fairy called Nix will take care of the entire reconciliation for me.

This was also around the time the Nix episode of the Off The Main Thread podcast was released, and that further pushed me to not give up on advancing my cool little declarative flake.

Then, recently, I’ve also converted my zsh aliases and init commands to that very same Nix flake, which means that when I run a single command1 on a new machine, I get:

  • most of my system preferences set up, including 24-hour time, my (controversial) preferred scrolling direction, and all of my persisted apps in the app dock
  • close to all of my apps: some through Nix packages directly, and some using nix-homebrew (mostly for GUIs, which tend to be angry when not having write permissions to their binaries and hence not being able to auto-update)
  • my favorite fonts
  • my default browser is set up as the default HTTP handler (through defaultbrowser
  • my git config, with my name, e-mail address, and GPG signing setup (although I still have to generate and import keys manually)
  • a fully set-up zoxide (if you don’t know what this is, you have to check it out, it will change the way you traverse folders on your system)
  • declaratively-managed login items (startup apps) for apps like Monitor Control, which I need to control the brightness on my external monitor

If you’re curious, you can check out my setup on GitHub. I feel like it’s almost perfect, but it has some limitations:

  • Some apps just aren’t on either Homebrew or Nix packages (like my video editing software of choice, Davinci Resolve)
  • Some customizations aren’t very straightforward (like maintaining the aforementioned login items or setting a screensaver, which I still wasn’t able to figure out)
  • The per-app setup sometimes isn’t granular enough and you still have to do a lot of setup within the packages you install2 (this is not an issue of Nix though)

Next on my list is to integrate the Nix package manager into my Gitpod dotfiles so that I have a consistent toolset for all my projects, no matter which one I’m working on.

  1. It’s not really a single command (because you have to first set up nix on the machine), but it’s close to it and becomes a single command after Nix is set up 

  2. For example, I would love to declaratively specify which of my Epic Games and Steam library items should automatically be installed on my machine