To flake or not to flake

In my opinion, as a Nix user, Flakes are safe to adopt from a functionality standpoint. They are basically just some syntax: https://github.com/colemickens/nixos-flake-example (a demo showing flakes and regular nix-build building the same store path from a configuration). Also, you can achieve almost the same functionality with hand-written fetchTarball calls, or by using niv.

However, there are some things flakes addresses that aren’t easily addressed without flakes. Consider, troubleshooting a nix-env -iA command failing for a one-off user, with Nix today…

  • wait, what is your NIX_PATH set to?
  • wait, what do you have in ~/.config/nixpkgs or overlays/? or wait, what about overlays.nix?
  • oh hey there’s ~/.config/nix too, but it probably doesn’t matter, hopefully?
  • what does nix-channel --list say?
  • Oh wait, you’re using nixos-rebuild, aka you’re probably actually using sudo nixos-rebuild… so you have to know to actually reconfigure your channels with sudo nix-channel
  • oh wait, also don’t forget sudo nix-channel cmds won’t affect nix-env commands.
  • oh and of course watch the sudo/sudo-less for (sudo) nix-channel --update too, you probably need both!

These things are not issue with flakes. Flakes bring locally, explicitly defined dependencies to Nix projects, and enable pure evaluation by default. That alone makes it easy for me to adopt flakes.

nix build github:colemickens/nixcfg/$REV#toplevel.slynux

will build the exact same store path for anyone regardless of their local nix/nixpkgs config. It feels like how nix is meant to work.


However, there are still some UX issues with flakes that prevent me from recommending it unreservedly:

Retrofitting flakes onto a repo isn’t hard in my experience. Add a flake.nix, plumb through outputs from default.nix that you want exposed, replace unversioned fetchTarball calls with flake inputs, remove uses of currentSystem.


As for “propagating overlaid nixpkgs”, I just expose it as an extra output attribute in my nixcfg repo. nixcfg#packages is just my config-local packages, but nixcfg#pkgs is a full nixpkgs with my overlays applied so that I can run nix profile install nixcfg#someOverlayPkg and have it work.

14 Likes