Skip to content

Instantly share code, notes, and snippets.

@bibijeebi
Last active April 5, 2026 16:10
Show Gist options
  • Select an option

  • Save bibijeebi/4ecf11cd8f214da6e738777485001e9b to your computer and use it in GitHub Desktop.

Select an option

Save bibijeebi/4ecf11cd8f214da6e738777485001e9b to your computer and use it in GitHub Desktop.

Condensed Guide to Using Snowfall Lib in a Nix Flake Repository

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.

Prerequisites

  • Nix installed with flake support enabled.
  • Basic understanding of Nix and flakes.

1. Initialize a Nix Flake

If you don't already have a flake.nix file in your repository, create one:

nix flake init

2. Add Snowfall Lib to Your Flake Inputs

Edit 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
    };
  };
}

3. Use mkFlake to Define Flake Outputs

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)
    };
}

4. Configure Snowfall Lib (Optional)

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";
        };
      };
    };
}

5. Organize Your Flake Structure

Snowfall Lib expects a specific directory structure under your root directory (default is . or ./nix if configured):

  • packages/ : Define Nix packages
  • overlays/ : Define Nixpkgs overlays
  • modules/ : Define NixOS, Darwin, or Home Manager modules
  • systems/ : Define system configurations
  • homes/ : Define Home Manager configurations
  • templates/ : Define flake templates
  • shells/ : Define development shells
  • checks/ : Define flake checks
  • lib/ : Define shared library functions

6. Define Packages

Create a package by adding a directory under packages/:

mkdir -p packages/my-package

Create packages/my-package/default.nix:

{ pkgs, lib, ... }:

pkgs.stdenv.mkDerivation {
  name = "my-package";
  src = ./src;
  buildInputs = [ pkgs.someDependency ];
  # Additional build parameters
}

7. Define Overlays

Add overlays under overlays/:

mkdir -p overlays/my-overlay

Create 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;
  });
}

8. Define Modules

Place modules in modules/nixos/, modules/darwin/, or modules/home/ depending on the target:

mkdir -p modules/nixos/my-module

Create 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";
  };
}

9. Define Systems

Add system configurations under systems/<system-arch>/system-name/:

mkdir -p systems/x86_64-linux/my-system

Create 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
}

10. Define Homes

Add Home Manager configurations under homes/<system-arch>/user@host/:

mkdir -p homes/x86_64-linux/user@my-system

Create 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
}

11. Define Templates

Templates are useful for sharing project structures. Add them under templates/:

mkdir -p templates/my-template

Place your template files inside this directory.

12. Define Shells

Create development shells under shells/:

mkdir -p shells/my-shell

Create shells/my-shell/default.nix:

{ pkgs, lib, ... }:

pkgs.mkShell {
  packages = [ pkgs.someTool ];
  # Additional shell setup
}

13. Define Checks

Add checks under checks/:

mkdir -p checks/my-check

Create checks/my-check/default.nix:

{ pkgs, lib, ... }:

pkgs.runCommand "my-check" { } ''
  echo "Running checks..."
  # Implement your checks
  touch $out
''

14. Automatic Importing and Exporting

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

15. Accessing Inputs and Libs

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 module

16. Configuration Options

You 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;
    };

17. Merging Custom Outputs

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";
    };
}

18. Advanced: Adding Modules and Special Args to Systems

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"; };
        };
      };
    };
}

Conclusion

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment