importNpmLock promise failure on nix develop

I believe this could be a transient error but I would still try to figure it out as it’s the first time I use this feature on a flake. Here’s my current flake.nix:

{
  description = "Hello World";

  inputs = {
  };

  outputs = { self, nixpkgs }:
		let
			systems = [
				"x86_64-linux"
				"aarch64-linux"
				"x86_64-darwin"
				"aarch64-darwin"
			];
			forAllSystems = f:
				nixpkgs.lib.genAttrs systems (system:
					f {
						pkgs = import nixpkgs { inherit system; };
					});
		in

		{
			devShells = forAllSystems ({ pkgs }: {
				default = pkgs.mkShell {
					packages = with pkgs; [
						git
                        uv
						importNpmLock.hooks.linkNodeModulesHook
						nodejs
					];
				};

				npmDeps = pkgs.importNpmLock.buildNodeModules {
					npmRoot = ./.;
					inherit (pkgs) nodejs;
				};
			});
		};
}

I have a ./node_modules folder installed and also have @vue/cli installed there. If I run nix develop, I get this error every time, even though everything seems to work as it should:

warning: Git tree '/Users/pocalypse/Develop/proletariat' is dirty
Executing linkNodeModulesHook
node:internal/fs/promises:953
  const result = await PromisePrototypeThen(
                 ^

Error: ENOENT: no such file or directory, scandir '/node_modules'
    at async Object.readdir (node:internal/fs/promises:953:18)
    at async main (/nix/store/4pfaf1vijsqqgs5l2l9fxjn2jp5l2s9k-link-node-modules.js:59:23) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'scandir',
  path: '/node_modules'
}

Node.js v24.14.0
Finished executing linkNodeModulesShellHook
pocalypse:proletariat pocalypse$ vue
Usage: vue <command> [options]

I’d love your input if somebody has any idea how I can debug this further, thank you in advance!

1 Like

You’re probably in a git repository with your node_modules directory in .gitignore. Flakes do not allow you to access un-tracked files.

Instead, the hook you’re trying to use is supposed to create a node_modules directory for you, without ever involving npm.

I haven’t used these, but try:

devShells = forAllSystems ({ pkgs }: let
  inherit (pkgs) importNpmLock;
in {
  default = pkgs.mkShell {
    packages = with pkgs; [
      git
      uv
      nodejs

      importNpmLock.hooks.linkNodeModulesHook
    ];

    # The crux is that this variable needs to be set in
    # the build env, without it the node modules
    # dir will not exist. It's not a separate devshell.
    npmDeps = importNpmLock.buildNodeModules {
      npmRoot = ./.;
      inherit (pkgs) nodejs;
    };
  };
});

Note that this will mean that you need to delete your node_modules. Nix will be fully in charge of managing your dependencies, even during development.

Thank you, that was exactly the problem. I initially removed node_modules from .gitignore but I added it back after I resolve the issue and things seems to work still.

Could it be possible that the gitignore was a red herring and the problem was only the location of importNpmLock.buildNodeModules outside of the build env?

Regardless, I consider this matter close. Thank you so much for the quick response.

Erm, yeah, sorry. I was just trying to explain why nix couldn’t see the directory even though you thought it was there. You’re not supposed to try tracking it.

1 Like