Snowfall Lib v2 has been released! You can given the new Quickstart Guide a try or head over to the Snowfall Lib Reference if you’d like to dig in to the details. There is also a Migration Guide if you’re coming from v1. This release includes a handful of new features like home-manager support, darwin modules, improved namespace handling, metadata, support for Snowfall Frost, and more .
For everyone else who has no idea what Snowfall Lib is…
Snowfall Lib is a Nix library that helps you wire up your Nix flake outputs. It introduces an opinionated file structure and automatically picks up and exports packages, overlays, modules, shells, systems, and libraries. Because Snowfall Lib handles all of the wiring, there are a lot of quality of life improvements like automatic overlaying of flake packages, easy access to your flake library (and the libraries of your flake’s inputs), as well as package and library namespacing to avoid conflicts.
If this sounds interesting to you, please give the Quickstart Guide a try! More detailed information about how Snowfall Lib expects things to be laid out can be found here: lib.mkFlake
And if you’d like a reference for using Snowfall Lib, I’ve been happily using it to manage my systems, modules, packages, overlays, and flake library for a while here: GitHub - jakehamilton/config: One Nix flake to rule them all.
How would you compare it to https://flake.parts ? Why would I choose your solution over the other?
flake-parts tries to do a lot and I found it to mostly make things more complicated. The thing that I need to happen is for my Nix flake outputs to be wired together from my other files. I want to avoid writing boilerplate as much as possible, but the module system that flake-parts uses tends to favor boilerplate and manual wiring.
Don’t get me wrong, I think flake-parts is neat. I just don’t think that it solves my problem particularly well.
Thank you for making the effort to publish.
Thanks for the effort @jakehamilton
This looks great from a first read.
Since I’m developing my nix stuff in a mono-repo I’m wondering if there is a limitation to use
snowfall within a subflake?
My use-case is that I have a
infra folder that contains all my server/ desktop/ laptop/ VM environment that would greatly benefit from the snowfall structure.
But that is not true for the rest of the monorepo.
Snowfall Lib should work just fine in a sub flake
Can you be selective about things? E.g. if I want to create lots of modules, but different subsets of those are applied to any particular system or set of systems?
You’ll want to create options to enable specific modules, just like how the modules in NixPkgs work.
I didn’t see any examples of this in your sample repo.
Not sure what that exactly refers to.
As an “advanced” beginner, I’ve figured enough out to build lots of my own packages in Nix, manage dev envs with Nix and manage a small fleet of nodes running on NixOS.
In my current flake, I just create files that have logic in them, then point to them, e.g.
modules = [
There appear to be some abstractions that Snowfall Lib provide that make things nicer, but also more confusing (to me at least).
The module system is pretty awesome, but you won’t get the full benefits if you’re only importing modules (applying configuration by default). The real power comes with options.
The modules available from NixPkgs work this way, they’re all imported but they specify options that can enable their functionality. For example: https://github.com/NixOS/nixpkgs/blob/5a237aecb57296f67276ac9ab296a41c23981f56/nixos/modules/services/web-apps/writefreely.nix#L134
This way you can enable only what you want to in each system or build abstractions on top of other modules. This doesn’t have much to do with Snowfall Lib since it’s the NixOS module system, but if it helps you can take a look at how I handle things in my configuration.
A module that specifies some options: https://github.com/jakehamilton/config/blob/072632650fa85a5b1ca56c6104b80f146eca10df/modules/nixos/hardware/networking/default.nix#L9
Your system configurations can enable only the modules that you choose: https://github.com/jakehamilton/config/blob/072632650fa85a5b1ca56c6104b80f146eca10df/systems/x86_64-linux/quartz/default.nix#L63
Note that my configuration uses a few helpers for some very common things (like instead of
something.enable = true I have
something = lib.plusultra.enabled). You don’t have to do this, these abstractions aren’t necessary. For reference, those helpers are here: https://github.com/jakehamilton/config/blob/072632650fa85a5b1ca56c6104b80f146eca10df/lib/module/default.nix
First of all, thank you, @jakehamilton, for your work. I actually haven’t tested it out yet, but now i’m actually thinking of moving my system config to snowfall.
Regarding the discussion about mosule system here: I really like the idea of modules, but sometimes they just get in the way. The issue I personally have is as follows. For my machines I use home-manager/master, but to ensure system stability for my partner I use home-manager/23.05. That’s why I get an error saying
no such option: **option-name** when I try to rebuild my partner’s system. Even if I disable all these options the module system just can’t digest the most modern options.
What I have to do is just import a module containing all this config conditionally inside my flake.nix, i.e. I have to resolve the problem at the top level and it’s clearly dirty. What do you think, how can snowfall deal with this? Actually, it’s not a very big deal, I think I can just do the same thing. But maybe you can propose a better solution.
Thank you for your time and attention~
This looks really neat, I think using file hierarchies to automatically define the flake outputs is a brilliant idea. I hope this library gets traction, if not, this idea itself.
One question: it seems that the library has a preference for
foo/bar/default.nix type of paths. Can you use