The right way to package apps with flakes (and install them)

Hi there,
I’ve successfully packaged an app with flakes instead of fetchFromGithub and managed to add it to my NixOS configuration. However it looks kind of ugly and I wonder if there is a better way of doing this. I also want to push it to NUR or something so the question can be worded as: what’s the right way to distribute packages with flakes?

(and why do so few people use flakes for packaging?)

Here’s what I did.
I’ve made a package like so (lumen/flake.nix):

{
  description = "A command-line tool that uses AI to streamline your git workflow - from generating commit messages to explaining complex changes, all without requiring an API key.";

  inputs = {
    nixpkgs.url = github:nixos/nixpkgs/nixos-unstable;
    flake-utils.url = github:numtide/flake-utils;

    lumen-src = {
      url = "git+https://github.com/jnsahaj/lumen?ref=HEAD";
      flake = false;
    };
  };

  outputs = { nixpkgs, flake-utils, lumen-src, ... }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
      in
      rec {
        packages.default = 
          let
            manifest = (pkgs.lib.importTOML "${lumen-src}/Cargo.toml").package;
          in
          pkgs.rustPlatform.buildRustPackage rec {
            pname = manifest.name;
            version = manifest.version;
          
            cargoLock.lockFile = "${lumen-src}/Cargo.lock";
          
            src = pkgs.lib.cleanSource "${lumen-src}";
          
            nativeBuildInputs = [ pkgs.pkg-config ];
            buildInputs = [ pkgs.openssl ];
          };
      }
    );
}

Then I added it to the inputs of NixOS configuration flake.nix:

inputs = {
  lumen.url = path:./lumen;
};

And finally I added it to home-manager (installed as a NixOS module) like this:

{ pkgs, inputs, ... }:

{
  home.packages = [
    inputs.lumen.packages.${pkgs.system}.default
  };
}

I consider flake = false an antipattern, flake inputs are really for flakes at the end of the day. I use npins to lock things like non-flake github inputs.

What you have is almost fine, although I’d recommend against flake-utils, it’s redundant and even misleading if you’re only supporting some subset of platforms. Also, subflakes are pretty much broken, lockfile-wise.

1 Like

Thank you! I’ll check npins.

Are subflakes flakes in the same directory as the main flake? Why are they broken? Does referring to it with an absolute path solve the issue?