Use module from unstable

Hello

I am trying to use a module from unstable in my otherwise 25.11 configuration. I am about to get completely frustrated as nothing seems to work. Can someone hint me to the right (and hopefully simple) solution?

Here is the relevant extract from my flake.nix:

{
  description = "System Flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
   };
   
 outputs = { self, nixpkgs, nixpkgs-unstable, ... }
 @inputs: 
 {
    nixosConfigurations = {
      "Laptop" = nixpkgs.lib.nixosSystem rec {
        system = "x86_64-linux";
        specialArgs = { inherit inputs; };
        modules = [
          ./machines/laptop-hardware-configuration.nix
          {hardware.cpu.intel.npu.enable = true;} # this needs to come from unstable as it is not in 25.11!
          ./desktop-environments/gnome.nix
     	  ./other-configuration.nix
        ];
       };
    };  
  };
}

Thanks in advance!

Michael

The manual has a relevant example. You need to disable the module that defines the option you want to set, insert the corresponding module from unstable, and then set the option. It may or may not ā€˜just work’; obviously a module from unstable may assume other things that are newly in unstable, and this technique doesn’t take that into account. Good luck!

1 Like

Thanks for the suggestion. I tried to implement it like so:

flake.nix:

{
  description = "System Flake";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.11";
    nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
   };
   
 outputs = { self, nixpkgs, nixpkgs-unstable, ... }
 @inputs: 
 {
    nixosConfigurations = {
      "Laptop" = nixpkgs.lib.nixosSystem rec {
        system = "x86_64-linux";
        specialArgs = { inherit inputs; };
        modules = [
          ./machines/laptop-hardware-configuration.nix
          ./npu.nix # see below!
          ./desktop-environments/gnome.nix
     	  ./other-configuration.nix
        ];
       };
    };  
  };
}

and

npu.nix:

{
  config,
  lib,
  inputs,
  ...
}:
{
  imports = [
    (inputs.nixpkgs-unstable + "/nixos/modules/hardware/cpu/intel-npu.nix")
  ];

  hardware.cpu.intel.npu.enable = true;
}

The problem with this approach is (as you already assumed) that the module references a package in unstable (ā€œpkgs.intel-npu-driverā€), which is not in 25.11, so the error message occurs:

       error: attribute 'intel-npu-driver' missing
       at /nix/store/7f0478ddr51i3r708dpkljnvmzwc2fhn-source/nixos/modules/hardware/cpu/intel-npu.nix:27:27:
           26|         enable = true;
           27|         extraPackages = [ pkgs.intel-npu-driver ];
             |                           ^
           28|       };

What would be the right way to ā€œchangeā€ that reference to ā€œpkgs-unstable.intel-npu-driverā€ or so?

You’d presumably need to rebuild that driver to use it with the stable Linux kernel. So what I’d try — again, just-working far from guaranteed with these sorts of tricks — is an overlay looking something like:

{
  nixpkgs.overlays = [
    (self: super: {
      intel-npu-driver = self.callPackage "${nixpkgs-unstable}/pkgs/by-name/in/intel-npu-driver/package.nix" { };
    })
  ];
}

Again, thanks a lot. This works indeed. My npu.nix file now looks like this:

{
  config,
  lib,
  inputs,
  ...
}:
{
  nixpkgs.overlays = [
    (self: super: {
      intel-npu-driver = self.callPackage "${inputs.nixpkgs-unstable}/pkgs/by-name/in/intel-npu-driver/package.nix" { };
    })
  ];

  imports = [
    (inputs.nixpkgs-unstable + "/nixos/modules/hardware/cpu/intel-npu.nix")
  ];

  hardware.cpu.intel.npu.enable = true;
}

This seems to manually recompile the driver.

Searching the forum here I found someone else solution for a similar problem (not a kernel driver, but a module) being very similar but with some distinct differences:

npu.nix (adapted from example in forum):

{   specialArgs, ... }: {
    imports = let
      inherit (specialArgs) system inputs;
      inherit (inputs) nixpkgs-unstable;
      unstablePkgs = nixpkgs-unstable.legacyPackages.${system};
      inherit (unstablePkgs) intel-npu-driver;
    in [
      # Override intel-npu-driver from nixpkgs-unstable
      {
         nixpkgs.overlays = [ (self: super: { inherit intel-npu-driver; }) ];
      }
      (nixpkgs-unstable + "/nixos/modules/hardware/cpu/intel-npu.nix")
    ];
    hardware.cpu.intel.npu.enable = true;
}

Both use overlays, but do I see it correctly that the second example does not recompile the driver itself?

(I am still fighting to understand all the details behind these overrides and how everything works in the background.)

That’s right. Both approaches have their uses: if inheriting a package directly from unstable, executables in that package generally will just work, because they bring all of their dependencies from unstable along with them. And of course, you don’t have to wait for a rebuild. But if you’re attempting to drag a library or kernel module from unstable to stable, binary compatibility will be an issue with that approach.

On the other hand, the callPackage approach, when it works, is ultimately slimmer, because it will reuse dependencies from stable instead of giving your system closure an extra copy of each. But if the packages used or referenced in the build have changed in significant ways, it may not work without further tweaks. Sometimes you can implement those tweaks relatively cleanly, for example by forcing newer dependencies in the { } of the callPackage call, or by using overrideAttrs to amend a phase or two. On some sad occasions, the best you can do is copy the .nix file from unstable into your local configuration repo, make modifications to it as needed, and callPackage that. I’m happy to hear that you didn’t need to do any of that this time!

1 Like