Packaging third-party software outside of nixpkgs

I’d like to hear some of your thoughts/experiences of packaging third-party software outside of nixpkgs.

nixpkgs is pretty big, so I think it’d be helpful if we make it easy to keep niche/‘leaf’ packages out of nixpkgs. Flakes seem to work fairly well for packages that are developed by Nix users, as the flake.nix, flake.lock and the lock file generated by dream2nix/gomod2nix/etc can be updated in tandem with regular development.

For projects that aren’t mostly developed by Nix users, what are good patterns for packaging those? Especially committing the generated lock files seems like it’d be painful: they’d easily go out of sync with the project itself (breaking the nix build and making bisecting hard), or updating them could be automated, but that’d lead to quite a bit of PR noise.

Another option is to keep the flakes in a separate repo, which seems to work fine-ish (e.g. raboof/nix-pisignage: nix flake to run pisignage-server -, raboof/nix-dependency-track: nix packaging of dependency-track -, but I’d be curious about recommendations.

What would be the best approach for projects that are nix-friendly but not primarily developed by nix users? Perhaps adding a second ‘nix-foo’ repository next to the ‘foo’ repository of the software being packaged?

Are you primarily talking about packaging or also about development?

If the project developers aren’t really keen about using Nix, packaging things in an extra Flake repo is probably the better idea. If the project already does proper releases, then I’d use the “classic” approach with the derivation fetching the sources itself. For projects where you want nightly builds that update often, I found it less hassle to use a Flake input for the sources (I packaged gpt4all for quite a while like that until they started proper releases and it got taken to Nixpkgs)

The main advantage in both cases is that you have control about the source version of your derivations, so you don’t suddenly find your Nix recipes not working because of a breaking change in the repo (very likely when the project is still regularly iterating on its dependencies). The latter can easily happen if you put your derivations inside the repo, but are the only person actually using them.

This also works if you (and only you) develop the project using Nix, just put a devshell along with it in the external flake. Using direnv, you can just put a .envrc in the main repo that references your flake and put it in .gitignore so you don’t disturb the others. It’s almost the same dev experience as a project with a native devShell.