Snowfall Lib is a powerful library that simplifies managing your Nix flake by providing an opinionated file structure and automating the generation of flake outputs. This guide will walk you through setting up Snowfall Lib in a flake-enabled Nix repository, focusing on defining flake outputs like homes, systems, overlays, packages, modules, templates, and shells.
- Nix installed with flake support enabled.
- Basic understanding of Nix and flakes.
If you don't already have a flake.nix file in your repository, create one:
nix flake initEdit your flake.nix to include snowfall-lib in the inputs section. Ensure you name it exactly snowfall-lib due to how the library processes inputs.
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.05"; # Use your desired Nixpkgs version
snowfall-lib = {
url = "github:snowfallorg/lib";
inputs.nixpkgs.follows = "nixpkgs"; # Ensures consistency with your nixpkgs input
};
};
}In the outputs section, use inputs.snowfall-lib.mkFlake to generate your flake outputs automatically.
{
outputs = inputs:
inputs.snowfall-lib.mkFlake {
inherit inputs; # Pass your inputs to Snowfall Lib
src = ./.; # The root of your flake (can be customized)
};
}Customize Snowfall Lib by adding a snowfall attribute:
{
outputs = inputs:
inputs.snowfall-lib.mkFlake {
inherit inputs;
src = ./.;
snowfall = {
root = ./nix; # Directory for your Nix files
namespace = "myflake"; # Namespace for your packages and lib
meta = {
name = "my-awesome-flake";
title = "My Awesome Flake";
};
};
};
}Snowfall Lib expects a specific directory structure under your root directory (default is . or ./nix if configured):
packages/: Define Nix packagesoverlays/: Define Nixpkgs overlaysmodules/: Define NixOS, Darwin, or Home Manager modulessystems/: Define system configurationshomes/: Define Home Manager configurationstemplates/: Define flake templatesshells/: Define development shellschecks/: Define flake checkslib/: Define shared library functions
Create a package by adding a directory under packages/:
mkdir -p packages/my-packageCreate packages/my-package/default.nix:
{ pkgs, lib, ... }:
pkgs.stdenv.mkDerivation {
name = "my-package";
src = ./src;
buildInputs = [ pkgs.someDependency ];
# Additional build parameters
}Add overlays under overlays/:
mkdir -p overlays/my-overlayCreate overlays/my-overlay/default.nix:
{ inputs, channels, lib, ... }:
final: prev: {
# Example: Override a package
my-overridden-package = prev.somePackage.overrideAttrs (old: {
version = "1.2.3";
src = inputs.someInput;
});
}Place modules in modules/nixos/, modules/darwin/, or modules/home/ depending on the target:
mkdir -p modules/nixos/my-moduleCreate modules/nixos/my-module/default.nix:
{ config, pkgs, lib, ... }:
{
options.myOption = lib.mkOption {
type = lib.types.bool;
default = false;
description = "An example option";
};
config = {
# Module implementation
assertions = lib.assertions.assert (config.myOption) "myOption must be true";
};
}Add system configurations under systems/<system-arch>/system-name/:
mkdir -p systems/x86_64-linux/my-systemCreate systems/x86_64-linux/my-system/default.nix:
{ config, pkgs, lib, ... }:
{
imports = [
./modules/nixos/my-module # Import your modules
];
system.stateVersion = "23.05"; # Adjust as needed
networking.hostName = "my-system";
# Additional system configuration
}Add Home Manager configurations under homes/<system-arch>/user@host/:
mkdir -p homes/x86_64-linux/user@my-systemCreate homes/x86_64-linux/user@my-system/default.nix:
{ config, pkgs, lib, ... }:
{
home.username = "user";
home.homeDirectory = "/home/user";
programs.zsh.enable = true;
# Additional Home Manager configuration
}Templates are useful for sharing project structures. Add them under templates/:
mkdir -p templates/my-templatePlace your template files inside this directory.
Create development shells under shells/:
mkdir -p shells/my-shellCreate shells/my-shell/default.nix:
{ pkgs, lib, ... }:
pkgs.mkShell {
packages = [ pkgs.someTool ];
# Additional shell setup
}Add checks under checks/:
mkdir -p checks/my-checkCreate checks/my-check/default.nix:
{ pkgs, lib, ... }:
pkgs.runCommand "my-check" { } ''
echo "Running checks..."
# Implement your checks
touch $out
''Snowfall Lib automatically:
- Imports all files in the structured directories.
- Exports them under appropriate flake outputs:
- Packages:
packages - Overlays:
overlays - Modules:
nixosModules,darwinModules,homeModules - Systems:
nixosConfigurations,darwinConfigurations, etc. - Homes:
homeConfigurations - Shells:
devShells - Checks:
checks - Templates:
templates - Library functions:
lib
- Packages:
Within your Nix files, you have access to:
inputs: Your flake's inputs, allowing you to use other flakes.lib: A merged library that includes your own functions and those from inputs.
Example usage:
{ inputs, lib, ... }:
let
myFunction = lib.myflake.myHelperFunction;
in
# Use myFunction in your derivation or moduleYou can customize Snowfall Lib behavior in mkFlake:
-
Namespace: Sets the namespace for your packages and lib.
snowfall.namespace = "my-namespace";
-
Aliases: Create default exports.
alias = { packages.default = "my-package"; shells.default = "my-shell"; };
-
Channels Config: Customize Nixpkgs configurations.
channels-config = { allowUnfree = true; config.firefox.enableWayland = true; };
If you need to add custom outputs not managed by Snowfall Lib:
{
outputs = inputs:
let
flakeOutputs = inputs.snowfall-lib.mkFlake {
inherit inputs;
src = ./.;
};
in
flakeOutputs // {
myCustomOutput = "Custom Value";
};
}You can add additional modules or special arguments to specific systems:
{
outputs = inputs:
inputs.snowfall-lib.mkFlake {
inherit inputs;
src = ./.;
systems = {
modules.nixos = [ inputs.someInput.nixosModules.someModule ];
hosts.my-system = {
modules = [ inputs.someInput.nixosModules.anotherModule ];
specialArgs = { customArg = "value"; };
};
};
};
}By organizing your Nix flake repository according to Snowfall Lib's structure and using mkFlake, you can automate the generation of your flake outputs and simplify the management of your Nix configurations. Snowfall Lib handles the importing and exporting of your packages, overlays, modules, systems, homes, templates, shells, and checks, making your flake more maintainable and scalable.
For more detailed information, refer to the Snowfall Lib documentation.