Nix Flakes best practices question

I’ve written a nix flake that can be used to generate other nix flakes for
Hakyll websites. It’s at GitHub - Radvendii/hakyll-flakes: Easy website generation with hakyll + nix flakes. I had a
few questions about best practices. (the questions won’t make sense out of
context though. you’ll have to look at the example in the readme)

There are two steps to make the website: compiling the website builder, and actually building the website. I have these separated as the “builder” package (which just builds the hakyll-based builder) and the “website” package (which does both, and leaves you with the website files).

  1. First question: Is “builder” a good name for this? I know “builder” has specific meaning in the nix ecosystem, but I couldn’t think of a better name.

hakyll-flake-gen needs to construct it’s own version of nixpkgs to guarantee that hakyll will work. It also takes in a set of build inputs that are needed for the second stage of building (applying the compiled hakyll builder to the website files).

  1. Second question: It is currently set up to pass back its modified copy of nixpkgs for the user to use when constructing the build inputs list. This isn’t actually necessary, because those build inputs don’t need hakyll. I figured it was better to use one consistent version of nixpkgs for the flake, rather than having those buildInputs come from the user’s nixpkgs, but now I’m not so sure. Which is better, having one consistent version of nixpkgs for all inputs, or having a simpler API (passing fewer things back and forth)?

  2. Third Question: Right now hakyll-flake-gen uses flake-util’s eachDefaultSystem, which means when you use it you have to use it as hakyll-flake.gen."${system}". I noticed that nix-bundle’s flake.nix has a bundlers.nix-bundle attribute that instead takes in system as an argument. (nix-bundle/flake.nix at 8e396533ef8f3e8a769037476824d668409b4a74 · matthewbauer/nix-bundle · GitHub) Is that better?

  3. Fourth question: Is there a naming convention for functions that generate flakes from inputs? I’ve called it gen (short for “generator”), but in nix-bundle it’s in bundlers.nix-bundle, and in flake-utils they’re under “lib”.

If there’s anything else I’m doing in a way that’s not ideal, let me know. This is just a first draft.


I figured out what I think is a better system (for questions 2 & 3)

I take in “system” as a parameter, and don’t pass back pkgs, but rather have an attribute hakyll-flake-gen.pkgs.${system} that the user can access if they want, but doesn’t get in the way if they don’t.

I agree with your idea for questions 2 and 3, but 1 and 4 being naming questions for a still-in-development feature, I’m not sure if there is a standard naming convention. For question 4 in particular, I’d think while it could be fine as is, a lib folder would make more sense and be more general, and is a practice done in a lot of other languages too.

If I understand correctly, the use case your tool covers is “I have a Hakyll website project, please wrap it in a Nix flake for me!”. This is in spirit similar to the *2nix list of tools:

  • cabal2nix turns a Cabal project into a Nix expression.
  • npm2nix does the same for NPM projects.
  • composer2nix
  • mvn2nix

The only major difference seems to be that you target flakes directly, while the other *2nix generally don’t. You could call your tool hakyll2nix or hakyll2flake.

1 Like

@lorenzleutgeb Ooh I like that, thanks! It probably makes sense then to restructure my project so that there’s a command line utility you can run that will produce a flake.nix and flake.lock file, and also a utility function you can run from inside a flake.nix file.
At least, from what I’ve seen the something2nix projects seem to work that way.

@gh0st mm yeah, maybe I’ll call it hakyll2flake.lib.mkFlake or something like that. that will make more sense also if hakyll2flake.defaultPackage is a package with a hakyll2flake binary.

I’ve decided to call it hakyll-flakes (GitHub - Radvendii/hakyll-flakes: Easy website generation with hakyll + nix flakes), and the main function is at hakyll-flakes.lib.mkAllOutputs. I think it has more in common with the mkDerivation function than with blah2nix projects, because those seem to all take in some other kind of generator (cabal, npm, etc), whereas this is just based on the inputs you give to the function.