Why Modules?

Declaring derivations as modules solves a number of issues.

For some more background information, check out the initial exploration of this idea at DavHau/pkgs-modules.

@edolstra 's talk about this topic is also worth watching.

Benefits

Deprecate override functions

Changing options of packages in nixpkgs can require chaining different override functions like this:

{
  htop-mod = let
    htop-overridden = pkgs.htop.overrideAttrs (old: {
      pname = "htop-mod";
    });
  in
    htop-overridden.override (old: {
      sensorsSupport = false;
    });
}

... while doing the same using dream2nix looks like this:

{
  htop-mod = {
    imports = [./htop.nix];
    name = lib.mkForce "htop-mod";
    flags.sensorsSupport = false;
  };
}

See htop module definition here.

Type safety

The following code in nixpkgs mkDerivation mysteriously skips the patches:

mkDerivation {
  # ...
  dontPatch = "false";
}

... while doing the same using dream2nix raises an informative type error:

A definition for option `[...].dontPatch' is not of type `boolean' [...]

Catch typos

The following code in nixpkgs mkDerivation builds without openssl_3.

mkDerivation {
  # ...
  nativBuildInputs = [openssl_3];
}

... while doing the same using dream2nix raises an informative error:

The option `[...].nativBuildInputs' does not exist

Environment variables clearly defined

dream2nix requires a clear distinction between known parameters and user-defined variables. Defining SOME_VARIABLE at the top-level, would raise:

The option `[...].SOME_VARIABLE' does not exist

Instead it has to be defined under env.:

{
  my-package = {
    # ...
    env.SOME_VARIABLE = "example";
  };
}

Documentation / Discoverability

No more digging the source code to find possible options to override.

Documentation similar to search.nixos.org can be generated for packages declared via dream2nix.

Every package built with dream2nix has a .docs attribute that builds an html documentation describing it's options.

Package blueprints

With dream2nix, packages don't need to be fully declared. Options can be left without defaults, requiring the consumer to complete the definition.

Flexibility

The nixos module system gives maintainers more freedom over how packages are split into modules. Separation of concerns can be implemented more easily. For example, the dependency tree of a package set can be factored out into a separate module, allowing for simpler modification.