Question About Nix Expressions

Quick Background: I am a daily user of both NixOS and Home-Manager, looking for the right level of coupling between the two. I’m very casually (slowly) learning Nix to answer different questions that I have like this one, so maybe this is trivial. Hoping someone who is more knowledgeable can help me out!

In the past few months I’ve learned how to both stable and unstable packages side-by-side in my configs (thanks LibrePhoenix!). Through the basic concatenation and a quick let in statement I can easily combine stable and unstable. Now, though, I want to learn more about combining and optimizing my configs.

What is the problem? – Right now I have what I’ll call the “Four File Solution” where I have two pairs of files for package management. The “problem” is that my lists of packages live in two places, so I have to edit two files to keep things consistent.

One for Home-Manager:

# home-packges.nix
{ pkgs, pkgs-stable, ... }:
let
  stablePkgs = with pkgs-stable; [ du-dust ];  
  unstablePkgs = with pkgs; [ ripgrep ];
in
{
  home.packages = unstablePkgs ++ stablePkgs;
}
# home.nix
...
import = [ ./home-packages.nix ];
...

One for NixOS:

# nix-packges.nix
{ pkgs, pkgs-stable, ... }:
let
  stablePkgs = with pkgs-stable; [ du-dust ];  
  unstablePkgs = with pkgs; [ ripgrep ];
in
{
  enviornment.systemPackages = unstablePkgs ++ stablePkgs;
}
# configuration.nix
...
import = [ ./nix-packages.nix ];
...

This leads to a problem where I need to edit two files to have this new package on both Home-Manager and NixOS. I would love to get down to what I’ll call the “Three File Solution”. Something like:

# common-packages.nix
{ pkgs, pkgs-stable, ... }:
{
    stablePkgList = with pkgs-stable; [ du-dust ];  
    unstablePkgList = with pkgs; [ ripgrep ];
}

Then, import the common list in both Home-Manager and NixOS:

# home.nix
...
import = [ ./common-packages.nix ];
home.packages = stablePkgList ++ unstablePkgList
...
# configuration.nix
...
import = [ ./common-packages.nix ];
enviornment.systemPackages = unstablePkgs ++ stablePkgs;
...

Why not just deal with the Four File Solution? – I totally can, and happily do. This problem is not a barrier to me using Nix in my day-to-day, but more of a “I wonder if there’s a better way” learning opportunity.

From my understanding I’m working with the following capabilities / limitations of Nix:

  • There are no global variables in Nix
  • The process I’m shoehorning my ideas into here is that I’m writing an expression to be evaluated; this is not a C paradigm where an import is effectively copy/pasting code in a cleaner way

Am I on the right track here? Is there a better way to approach this?

Why do you want to add the same list of packages to home.packages and environment.systemPackages? Either one alone would suffice to make those packages available to you.

Anecdotally, I have had a ton of issues mixing my Home-Manager and NixOS configs. So I have gone the route of intentionally separating them – i.e. having a package in my Home-Manager config does not make it available on my NixOS system. :slight_smile:

Well obviously, because user config cannot manage system config, that would be the tail wagging the dog.

But putting the package in environment.systemPackages makes it available to all users, it’s redundant to put it in the HM config as well.