How to invoke `nix-shell -p` for packages not in Nixpkgs?

Is it even possible or one always has to wrap such packages in a shell.nix? According to the nix-shell man page:

   --packages / -p packages...
       Set up an environment in which the specified packages are
       present. The command line arguments are interpreted as
       attribute names inside the Nix Packages collection. Thus,
       nix-shell -p libjpeg openjdk will start a shell in which
       the packages denoted by the attribute names libjpeg and
       openjdk are present.

Would this be done somehow using the -I path common option?

For example, mach-nix is not yet in Nixpkgs, and its readme gives the install option to use

nix-env -if -A mach-nix

but I try to avoid nix-env in favor of nix-shell because it tends to cause surprises down the line. The closest I got without wrapping it in a shell.nix is this:

$ nix-shell -A mach-nix
[nix-shell]$ genericBuild
[nix-shell]$ $out/bin/mach-nix --version

There are probably more, but I’m aware of at least two:

  • The “clean” way: add the package(s) to your system via overlay, where you can just reference them via -p <pkgname>
  • -p can accept an expression, so you can also do something ad hoc like: nix-shell -p '(callPackage (fetchTarball {}).mach-nix'

if you have flakes enabled:

nix shell github:DavHau/mach-nix


I would just capture mach-nix in your shell.nix or devShell in your flake.nix. Then pair it with direnv to allow you to bring it into your shell when you need it for a particular project


Without resorting to flakes, run nix-shell foo.nix where foo.nix is as follows:

  pkgs = import <nixpkgs> {};
  mach-nix = import (builtins.fetchTarball {};
  pkgs.mkShell {
    buildInputs = [ mach-nix.mach-nix ];

Thank you so much to all of you!

@abathur I still have to get to learn overlays so this would be perfect opportunity. I also didn’t know that nix-shell -p actually accepts an expression! Is this a well-known fact? I’ve never seen it used like this, and the docs I’ve read so far never mentioned. Thanks! (callPackage is another one that I haven’t been able to wrap my head around yet, but it’s a running joke that experienced Nix people constantly explain it to newcomers:)

@jonringer You are ahead one step because my next question down the line would’ve been how to use (if possible) nix-shell with flakes. Thank you for mentioning direnv! I have to look into that.

@symphorien Thanks! Forgot to mention that this is exactly how I use mach-nix (and other non-Nixpkgs packages) at the moment, but now it is explicit for everyone.

This issue has just been opened: