nixnixosnixpkgshome-manager

How to set a custom package version in nix home-manager?


I'm looking for an idiomatic way of setting a custom package via home manager (I use nix package manager on MacOS)

I managed to set a custom version for pnpm package using fetchFromGitHub, but I'm not sure if it's an idiomatic way.

{ config, pkgs, ... }:

let
  pnpm94 = import (pkgs.fetchFromGitHub {
    owner = "NixOS";
    repo = "nixpkgs";
    rev = "c3392ad349a5227f4a3464dce87bcc5046692fce";
    sha256 = "1klhr7mrfhrzcqfzngk268jspikbivkxg96x2wncjv1ik3zb8i75";
  }) {
    inherit (pkgs) system;
  };
in

{
 #......

  home.packages = with pkgs; [
    pnpm94.pnpm <=== our custom version of pnpm

    #... the rest of the packages
  ];
}

Is it correct approach? Or there's a more elegant alternative?


Solution

  • Yes, this is a correct approach. Since NixOS/nixpkgs is reproducible, the only way to use a specific version of a package is to pin the associated version/commit of nixpkgs. This method is independent of whether you're using Home Manager or not.

    The simplest implementation is the one you proposed where a custom instance of pkgs is imported:

    { config, pkgs, ... }:
    
    let
      pkgs_pnpm94 = import (pkgs.fetchFromGitHub {
        owner = "NixOS";
        repo = "nixpkgs";
        rev = "c3392ad349a5227f4a3464dce87bcc5046692fce";
        sha256 = "1klhr7mrfhrzcqfzngk268jspikbivkxg96x2wncjv1ik3zb8i75";
      }) {
        inherit (pkgs) system;
      };
    in
    
    {
      home.packages = [
        # Regular packages
        pkgs.curl
    
        # "custom" version of `pnpm`
        pkgs_pnpm94.pnpm
      ];
    }
    

    If your configuration is organized by a flake, another way of doing it is adding this specific version of nixpkgs as an input and create an overlay. Here's an illustrative example:

    {
      inputs = {
        nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
        nixpkgs_pnpm94 = {
          url = "github:NixOS/nixpkgs/c3392ad349a5227f4a3464dce87bcc5046692fce";
        };
        home-manager = {
          url = "github:nix-community/home-manager";
          inputs.nixpkgs.follows = "nixpkgs";
        };
      };
    
      outputs = { self, nixpkgs, nixpkgs_pnpm94, ... }:
      let
        pkgs_pnpm94 = import nixpkgs_pnpm94 { inherit system; };
        overlay = final: prev {
          pnpm = pkgs_pnpm94.pnpm;
        };
        pkgs = import nixpkgs { inherit system; overlays = [ overlay ]; };
      in
      {
        homeConfiguration.default = home-manager.lib.homeManagerConfiguration {
          modules = [ ./home.nix ];
          inherit pkgs system;
        };
      };
    }
    

    In this example: