Override package with local build

I know how to use an overlay to build a different revision of a package, via Overlays - Official NixOS Wiki . However, the build process for the package takes a long time and a lot of storage space, and it seems to rebuild the package whenever I run sudo nixos-rebuild switch --upgrade.

I would like to build the program with the override once, locally, then replace the overlay with my local version of the package, but I cannot find any documentation on how to do that. Please help! TIA

Pin the dependencies of the package you overlay.

And of course all the dependencies of dependencies. And theirs.

Aka, pin another nixpkgs Input, overlay that, and use your software from there. Do not update that input until you are ready to do so.

I’m not super familiar with the whole process. I’m going to make some inferences and please correct me where I’m wrong:

The reason the package is getting rebuilt despite keeping the same revision is because of dependencies updating in nixpkgs-unstable? Most compiled languages don’t package in the dependencies in the finished binary, so if I were able to compile the program locally, I would maybe still need to pin the dependencies so the binary keeps working anyway?

So the solution for me who am using flakes is to add a nixpkgs-stable.url = "https://channels.nixos.org/nixos-26.05-small/nixexprs.tar.zst"; (assuming nixpkgs/pkgs/by-name/nu/nushell/package.nix at 385da87a3a8fe041e18f18c72e0f6529a454a749 · NixOS/nixpkgs · GitHub exists), and then using the package from there instead.

Annoyingly, I can’t get over the final hurdle of using the package, since I’m getting attribute 'nushell' missing on my inputs.nixpkgs-stable.nushell.overrideAttrs.

That should be inputs.nixpkgs-stable.legacyPackages.${system}.nushell.overrideAttrs where ${system} is your system’s architecture e.g. x86_64-linux.

Yes. This is the fundamental premise of nix. If a dependency changes, the dependee is different as well.

Ahh thanks. So the package builds fine, but when I add the override to the GitHub revision I want, I get the following error:

nushell> error: rustc 1.95.0 is not supported by the following packages:
nushell>   nu@0.115.2 requires rustc 1.96.1
...

I think this means that the version of rustc in nixos-26.05-small is too old for the version of the package I’m overriding to. It seems like what I need is a snapshot of nixos-unstable but frozen in time around now. Is there a way to do that?

As a complete aside, I’m curious about the need to include extraSpecialArgs = { inherit inputs; }; in my home-manager config in order to recognise the inputs.nixpkgs-stable attribute. I’ve had lines like the following two in my home manager config previously without needing extraSpecialArgs:
package = inputs.xdp-termfilepickers.packages.${pkgs.stdenv.hostPlatform.system}.default;
imports = [ inputs.noctalia.homeModules.default ];

Yes, use github:nixos/nixpkgs/<SHA1 of the commit> as the inputs URL.

Then you had inputs in scope through other means.

What other means are there? I’d quite like to keep the lines of code which put it in scope consistent across my uses of it, and in the same places as I use it.

Maybe you have been in the flake.nix where the inputs are usually in scope, or had a HM module nested in system, where you had the inputs in scope through system. We can’t really know without seeing any code or context.

My system is rather weird. I have

outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; }
      (inputs.import-tree ./modules);

and a modules/lib.nix with

options.flake.lib = lib.mkOption {
  type = lib.types.attrsOf lib.types.unspecified;
  default = { };
};

config.flake.lib = {
  mkSystem = name: inputs.nixpkgs.lib.nixosSystem {
    system = "x86_64-linux";
    modules = with inputs; [
      self.modules.nixos.${name}
      self.modules.nixos.core
      { networking.hostName = name; }

      home-manager.nixosModules.home-manager
      {
        home-manager = {
          #extraSpecialArgs = { inherit inputs; };
          useGlobalPkgs = true;
          useUserPackages = true;
          users.laura.imports = [
            self.modules.homeManager.${name}
            self.modules.homeManager.core
          ];
        };
      }
    ];
  };
};

and modules/hosts.nix with

  flake.nixosConfigurations = with inputs.self.lib; {
    spinifex = mkSystem "spinifex";
  };

flake.modules.nixos.spinifex = {
  imports = with inputs.self.modules.nixos; [
...
  ];
};

flake.modules.homeManager.spinifex = {pkgs, ...}: {
  imports = with inputs.self.modules.homeManager; [
...
  ];
};

Pretty much every other file is included via a chain of flake parts module imports, so the files with external module imports and the file with an external package are the same structurally as the one I’m trying to get the alternate nixpkgs from. Only the lattermost needs the extraSpecialArgs. I’m not familiar enough with any of the moving parts to have a good grasp of how the system works. A friend helped me set it up.

Are both of these flake-parts modules? There you have the inputs in the module args by default.

Those 2 are nearly the only files in modules/ which aren’t flake part modules. The others which aren’t are just an imports = [ inputs.flake-parts.flakeModules.modules ];, a systems = ["x86_64-linux"];, and my generated hardware configuration.

Both do set flake, which is neither a system nor HM option, therefore I am pretty much convinced they are flake part modules.

And also the imports line as well as the systems line, only make sense in a flake parts module.

I’m not sure of the best forum to seek general understanding of my system, since this is now far from the original question, but here’s it is in case I haven’t described whats going on right.

There are only FP modules in the modules folder.

The reason why you hade to add inputs to HMs extraSpecialArgs is, because you use HMs module args in https://git.gay/pimgit/dotfiles/src/commit/44c9dad1bb644343e81c0694e248aa3afba23e25/modules/shell.nix#L2, rather than the FP modules args, which you use everywhere else.

PS: If you have to ask others, to help you understand your setup, it might be the time to delete the setup and build one you understand yourself.