Using `flake-parts` to quickly render a Markdown / org-mode site

Some of you are probably already aware of flake-parts which helps “modularize” flake.nix. This is especially useful on monorepos where the top-level flake.nix tends to get complicated and huge over time.

flake-parts can also be used to provide a nixos-module like feel.

For example, if you have a directory of Markdown or org-mode files, you can drop the following flake.nix to it, and run nix build to get a statically build website, or nix run to run a live updating view of those plain-text files.

{
  nixConfig.extra-substituters = "https://srid.cachix.org";
  nixConfig.extra-trusted-public-keys = "srid.cachix.org-1:3clnql5gjbJNEvhA/WQp7nrZlBptwpXnUk6JAv8aB2M=";

  inputs = {
    emanote.url = "github:srid/emanote";
    nixpkgs.follows = "emanote/nixpkgs";
    flake-parts.follows = "emanote/flake-parts";
  };

  outputs = inputs@{ self, flake-parts, nixpkgs, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      systems = nixpkgs.lib.systems.flakeExposed;
      imports = [ inputs.emanote.flakeModule ];
      perSystem = { self', ... }: {
        emanote.sites."default" = {
          layers = [ ./. ];
          layersString = [ "." ];
        };
      };
    };
}

(This uses https://emanote.srid.ca/ to build/serve the site).

7 Likes

And what is innovative about that use case? Couldn’t I already do that before just with different syntax?

1 Like

This part:

Because flake-parts is using the nix module system. It means that a flake can now impact the host flake output.

This is for scenarios where the host flake gets taken over by one of the input flakes. In a framework-like approach.

I prefer explicit wiring because it’s generally more composable. But I can see the appeal of the above approach if you want to reduce the amount of nix that your users need to know.

4 Likes

So basically it ports the nixos module system to just flakes without nixosConfiguration.

2 Likes

I prefer explicit wiring because it’s generally more composable.

You can use explicit wiring on top of the basic flake output attribute options. That’s a similar level of abstraction to what the systemd.* options offer in NixOS. The same trade-offs apply in both configuration systems. If you write all of your own systemd units, you similarly get much more control. Want to run multiple postgres servers on a single NixOS? Not possible with the module, but you can generate your own units for each server with mapAttrs'. The postgres module won’t be stopping you, while it does help others who have simpler requirements.

So basically it ports the nixos module system to just flakes without nixosConfiguration.

The module system is already portable :slight_smile:. Basically none of the specific options in NixOS carry over to flake-parts, and that’s part of the reason why it’s light weight. You can of course have nixosConfigurations and nixosModules like you would in any other flake, and those behave pretty much the same way they would otherwise.