The overlay is set up correctly, but you’re misunderstanding how overlays work. Overlays don’t magically create or install packages; that you still need to do yourself.
An overlay does exactly what it says on the tin - it “overlays” some stuff on top of the normal nixpkgs contents. I.e., by setting some attribute (read dictionary key in JavaScript lingo) in the overlay’s attrset (dictionary), nix will put the contents of what you specify in the nixpkgs used for your build later on.
In other words, you’ve created a rescript
attribute, and if you use pkgs.rescript
anywhere in your configuration it will refer to the value you set there.
What you also fail to realize is that nix is lazy. Just because you created that attribute doesn’t mean nix will use it, or even build whatever you define. You actually need to use the attribute somewhere where nix is forced to do something with it, like in environment.systemPackages
. So, if you set:
environment.systemPackages = with pkgs; [ rescript ];
Anywhere in your config, that will actually refer to the package you tried to create there, and try to include it in your system path.
Unfortunately, this won’t work. The value of your attribute is going to try and evaluate, find that the original nixpkgs didn’t contain a rescript
, and therefore there is no super.rescript
whose override function you could use.
You’ll need to write an actual nodejs package instead of trying to override something. This, unfortunately, isn’t trivial, because npm is npm and a massive pain to work with due to thousands of nested dependencies. The documentation for this is in this section of the nixpkgs manual, but it’s quite the topic: Nixpkgs Reference Manual
To include it in a devShell
, the easiest option for overriding packages is simply to import the flake, and set the overlays
option:
let
overlays = [<your overlays>];
pkgs = import nixpkgs { inherit overlays; };
in {
devShell = pkgs.mkShell {
name = "proj-shell";
buildInputs = with pkgs; with pkgs.nodePackages; [
# dev packages
nodejs-16_x
bs-platform
node2nix
yarn
rescript # If set in your overlays, now works
python39
];
shellHook = ''export PATH="./node_modules/.bin:$PATH"'';
};
});
This works because the flake will resolve to the actual directory of the nixpkgs you refer to in the inputs, and therefore import
-ing it will import the normal nixpkgs default.nix
, which in turn just calls the function from the file I link to earlier. You can also set any of the other arguments of that function - config
is especially useful, and can be used to allow non-free applications and such for nixpkgs that aren’t configured with your system configuration.
Note that this is slower than your version, because import
-ing nixpkgs actually requires resolving a bunch of things, whereas referring directly to the legacyPackages
does not - when you need to overlay there is no way around that, though.
That said, if you want to create a new package, it’s probably better to do something like this:
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;
in {
devShell = pkgs.mkShell {
name = "proj-shell";
buildInputs = with pkgs; with pkgs.nodePackages; [
# dev packages
nodejs-16_x
bs-platform
node2nix
yarn
(callPackage ./rescript.nix { })
python39
];
shellHook = ''export PATH="./node_modules/.bin:$PATH"'';
};
});
The callPackage
there is a useful helper that just takes a function and gives it all the arguments it asks for from pkgs
, and is generally used to create packages. Read the nix pills to learn how it works My intention there is to say “do whatever you would to create a package”, which might not be obvious if you don’t know how to do that yet. I’d recommend reading this: https://nixos.org/manual/nix/stable/expressions/simple-expression.html and this too: Nixpkgs Reference Manual
I realize this is all a lot to take in, but I hope it helps - ask away if you need more help! On the up side, once you grok all this there’s not much else to learn about nix.
Overall, I’d suggest learning how to do this with something more straightforward than npm packages. It’s not the easiest thing to understand, and the complexities of thousands of dependencies will just make it harder.
Also, maybe take it one step at a time; understand how to package something with nix, then understand how to include that in your devShell
, and then understand how to include packages in your overlay. After that you can learn about override
(and more practically, overrideAttrs
), which is how you make small changes to existing packages, and the typical use case for overlays.