Mixing flakes and shell.nix

Hello,

I’ve got a darwin nix setup using flakes. There are a few git repo’s I have that I don’t want to use flakes with, but would like to still have a nix shell. Given I don’t have any channels setup, when I try to execute the shell, it fails due to no nixpgks being specified. I resolved that issue by manually setting the NIX_PATH to nixpkgs=channel:nixos-23.11. This works perfectly, but for a very small shell, it takes forever to spin up the shell every time. I’m guessing that this is because nix is pulling nix packages every time I execute the shell? Is there any way I can cache this outside of manually cloning and referring to a local folder instead of using the channel specifier?

ex (takes 3-5 minutes every time):

    { pkgs ? import <nixpkgs> {} }:
    let
    
      NPM_CONFIG_PREFIX = toString ./localignore_nix/bin;
    
    in pkgs.mkShell {
      buildInputs = [
        pkgs.nodejs-18_x
      ];
    
      inherit NPM_CONFIG_PREFIX;
    
      shellHook = ''
        export PATH="${NPM_CONFIG_PREFIX}/bin:$PATH"
      '';
    }

Yes, don’t use NIX_PATH, especially in combination with channels. Ideally you’d just read flake.lock in your Nix language code, which is what flake-compat is supposedly for. The other way round, i.e. somehow trying to make Nix read foreign lockfiles, is probably futile.

Still, enabling forward compatibility with flakes is more than just a bit of a pain, and there now at least 4 implementations with varying degrees of maintenance:

Ideally all you’d do is fromJSON the lockfile, and use builtin fetchers on the specified sources. Since fetch-tree is now its own experimental feature separate from flakes, if you trust that to ever become stable, the following may already be enough:

sources = builtins.mapAttrs
  (_: value: builtins.fetchTree value.locked)
  (builtins.fromJSON (builtins.readFile ./flake.lock)).nodes;

Regardless of how you obtain this sources attribute set, you can then go on to import from that in at the top level thanks to the beautiful fact that destructured arguments have its own scope:

{
  sources ? /* may as well get this from a helper file */,
  system ? builtins.currentSystem,
  pkgs ? import sources.nixpkgs { inherit system; config = {}; overlays = []; },
}:
# ...
2 Likes