Is there advantages to multiple Nix Flake Packages?

I’m not really understanding the best practice of the output packages. If I was to build a website, would I want a separate package for say my images, my styles, my scripts, and then have the default package import all of them for building, or is this all just a part of the main site’s derivation? Where do you draw the boundaries? The biggest reason I would want the separation is the caching aspect for CI and Cachix, but I did not see any significant speed ups so maybe I’m overthinking it.

1 Like

I’d say it entirely depends on the situation, how much work you’re willing to do, how much time you can actually save, how flexible are the tools you’re using, etc.
I think that generally, tools that nix people build[^1] value no/low maintenance before granularity of derivations.
For example, naersk doesn’t require you to maintain additional files but you only[^2] get compilation split in 2, if you don’t change dependencies, you only have to rebuild the project, if you do change the dependencies, you have to rebuild the whole thing.
You could imagine a hypothetical alternative[^3] in which each dependency is compiled in one derivation, and as such changing dependencies only affects the minimal set in the dependency graph, but you have to keep an additional index up to date, which your team may have trouble with.

When you say you didn’t see significant speedups, that could be interpreted in a couple of ways:
Are changes to script sources invalidating images or styles? If so, you’ll want to reduce how much is passed in the src of each derivation using lib.cleanSourceWith
Or maybe, does substituting end up taking more time than just building? Such as in cases where the output size is large (and therefore slow to download) but the computation is fairly fast. In those cases, you’d probably want to play with allowSubstitutes = false;/preferLocalBuild = true; (although they’re potential footguns from what I remember?)

[^1]: nmattia comes to mind :stuck_out_tongue_winking_eye:
[^2]: That’s pretty good to begin with
[^3]: Is that what crate2nix is?

2 Likes

I think for a single static website a single package makes sense. You’re unlikely to get any benefit from testing each component in isolation beyond unit tests that are still possible with a single package.

You can always run integration testing on the final package, and I think it makes more sense to do so on the fully bundled package.

For state-of-the-art bundling purposes I’d suggest using parcel or webpack, as there is tooling surrounding it that makes a lot of sense and softly forces you into good practices (more on the parcel side than webpack side), though packaging nodejs things with nix is admittedly nontrivial.

1 Like