Referencing the output of writeShellApplication as a package in another nix file

I have a small inlined script I have added to my system packages like that:

systemPackages = with pkgs; [
...
      (
        pkgs.writeShellApplication {
          name = "screenshot";
          runtimeInputs = with pkgs; [ slurp swappy grim ];
          text = ''
            ${pkgs.grim}/bin/grim - g "$(${pkgs.slurp})" - | ${pkgs.swappy} -f -
          '';
        })
...
];

I would like to reference the script screenshot and gets its true path in another nix file (a sway keybind). How can I reference this “package” through the pkgs variable in the other nix file ?

You can do it through an overlay:

nixpkgs.overlays = [ (final: prev: {
  # use `final` instead of `pkgs` in overlay for dependencies, as a general principle
  your-screenshot-thing = final.writeShellApplication { ... };
}) ];

Then something like "${pkgs.your-screenshot-thing}/bin/screenshot"

Aside: you likely don’t need to use both writeShellApplication’s runtimeInputs and the string interpolation.

writeShellApplication will set a PATH that includes these packages for normal runtime path lookups, while string interpolation is writing in the absolute paths to the executables (requiring no runtimenpath lookups).

You can also do this by writing a module. I have an example defined in this file and you can search the repo for xmodmap-config to see how I make use of it in two other modules.

Hope this helps!

If you are doing it from separate modules, then an overlay would be the “de facto” way to create a long lived, globally available binding for your custom package.

If you are doing it in the same module then a simple let binding would do. Of course, writing a module is a valid option to be able to reference something like a package option, but seems excessive in this case.

An overlay is definitely what I was looking for !
Tested it and it worked exactly as intended.

Thank you all.

1 Like