Well, to begin with you could simplify your example, remove the redundant evaluations and reduce the scope of your with
for clarity:
{
description = "Sample Nix ts-node build";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
pnpm_851.url = "github:nixos/nixpkgs?rev=d81de9fc07060ba680fae01da33aa6390d2a2666"; # Revision where pnpm is at version 8.5.1
};
outputs = { self, nixpkgs, flake-utils, pnpm_851, ... }:
flake-utils.lib.eachDefaultSystem(system:
let
pkgs = nixpkgs.legacyPackages.${system};
pnpm = pnpm_851.legacyPackages.${system}.nodePackages.pnpm;
in {
devShells.default = pkgs.mkShell {
packages = with pkgs; [
awscli2
protobuf
pnpm
nodePackages.ts-node
nodePackages.prettier
nodejs_16
];
# We'd need to extract token and such in a developer specific .envrc
NPM_TOKEN = "test";
};
}
);
}
You can also reduce it to just “touching it in two places”, I guess:
{
description = "Sample Nix ts-node build";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
pnpm_851.url = "github:nixos/nixpkgs?rev=d81de9fc07060ba680fae01da33aa6390d2a2666"; # Revision where pnpm is at version 8.5.1
};
outputs = { self, nixpkgs, flake-utils, pnpm_851, ... }:
flake-utils.lib.eachDefaultSystem(system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
packages = with pkgs; [
awscli2
protobuf
pnpm_851.legacyPackages.${system}.nodePackages.pnpm
nodePackages.ts-node
nodePackages.prettier
nodejs_16
];
# We'd need to extract token and such in a developer specific .envrc
NPM_TOKEN = "test";
};
}
);
}
But that becomes a question of style rather than implementation. I’m not sure this is more readable. Garnish with map
s over an @ inputs
as you see fit.
You can also indeed alternatively use overrideAttrs
, although this involves some tradeoffs:
{
description = "Sample Nix ts-node build";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils, ... }:
flake-utils.lib.eachDefaultSystem(system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
devShells.default = pkgs.mkShell {
packages = with pkgs; [
awscli2
protobuf
nodePackages.ts-node
nodePackages.prettier
nodejs_16
(nodePackages.pnpm.overrideAttrs (old: {
src = fetchurl {
url = "https://registry.npmjs.org/pnpm/-/pnpm-8.5.1.tgz";
sha256 = "W6elL7Nww0a/MCICkzpkbxW6f99TQuX4DuJoDjWp39X08PKDkEpg4cgj3d6EtgYADcdQWl/eM8NdlLJVE3RgpA==";
};
}))
];
# We'd need to extract token and such in a developer specific .envrc
NPM_TOKEN = "test";
};
}
);
}
This only overrides the pnpm source specifically, which means that the build may break if something else about its build process changes eventually.
The next step up from there is to write a package for it from scratch. You can either follow the instructions in the nixpkgs manual for this or use dream2nix
to convert pnpm
into a package whose checksum you control via a package.json
.
Which is best depends on how permanent this pin should be. For a short-term fix I’d stick to the gist of your current solution, if it’s something you’d like to keep longer-term write a custom package. The override is iffy, it will probably work, but I wouldn’t trust it long term, and I think I prefer using the pin to an old version of nixpkgs.