Modify flake now that defaultPackage is deprecated

I understand that defaultPackage in flakes is deprecated.

After reading the above issue, I’m not clear on what I should use instead. And the flake templates (I’m on unstable) still use defaultPackage. I couldn’t find any examples online.

How should I modify the following flake?

{
  description = "a very simple and friendly flake";

  # Nixpkgs / NixOS version to use.
  inputs = {
    nixpkgs.url = "nixpkgs/nixos-21.05";
  };

  outputs = { self, nixpkgs }:
    let

      # to work with older version of flakes
      lastModifiedDate = self.lastModifiedDate or self.lastModified or "19700101";

      # Generate a user-friendly version number.
      version = builtins.substring 0 8 lastModifiedDate;

      # System types to support.
      supportedSystems = [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];

      # Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'.
      forAllSystems = nixpkgs.lib.genAttrs supportedSystems;

      # Nixpkgs instantiated for supported system types.
      nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; overlays = [ self.overlay ]; });

    in

    {

      # A Nixpkgs overlay.
      overlay = final: prev: {

        hello-flake = with final; stdenv.mkDerivation rec {
          name = "hello-flake-${version}";

          src = ./.;

          unpackPhase = "true";

          buildPhase = ":";

          installPhase =
            ''
              mkdir -p $out/bin
              cp $src/hello-flake $out/bin/hello-flake
              chmod +x $out/bin/hello-flake
            '';
        };

      };

      # Provide some binary packages for selected system types.
      packages = forAllSystems (system:
        {
          inherit (nixpkgsFor.${system}) hello-flake;
        });

      # The default package for 'nix build'. This makes sense if the
      # flake provides only one package or there is a clear "main"
      # package.
      defaultPackage = forAllSystems (system: self.packages.${system}.hello-flake);
    };
}

I should mention that I did try changing

  defaultPackage = forAllSystems (system: self.packages.${system}.hello-flake);

to

 defaultPackages.default = forAllSystems (system: self.packages.${system}.hello-flake);

But when I try to run that version, I get

$ nix run "git+https://codeberg.org/mhwombat/hello-flake?ref=main&rev=e7820bd6396380686bc389b9a3f6db68e0bfaef1"
error: flake 'git+https://codeberg.org/mhwombat/hello-flake?ref=main&rev=e7820bd6396380686bc389b9a3f6db68e0bfaef1' does not provide attribute 'apps.x86_64-linux.default', 'defaultApp.x86_64-linux', 'packages.x86_64-linux.default' or 'defaultPackage.x86_64-linux'
       Did you mean defaultPackages?

Templates still using deprecated patterns is unfortunate. Although perhaps they are conservative for compatibility purposes?

Anyway, this is what your flake outputs are right now:

]$ nix flake show
path:/home/justinas/flake-playground3?lastModified=1676741462&narHash=sha256-c+YBWvNncs7UCgLZ8vHQ3K3X+G+PNzhiHa1etILyELI=
├───defaultPackage
│   ├───aarch64-darwin: package 'hello-flake-20230218'
│   ├───aarch64-linux: package 'hello-flake-20230218'
│   ├───x86_64-darwin: package 'hello-flake-20230218'
│   └───x86_64-linux: package 'hello-flake-20230218'
├───overlay: Nixpkgs overlay
└───packages
    ├───aarch64-darwin
    │   └───hello-flake: package 'hello-flake-20230218'
    ├───aarch64-linux
    │   └───hello-flake: package 'hello-flake-20230218'
    ├───x86_64-darwin
    │   └───hello-flake: package 'hello-flake-20230218'
    └───x86_64-linux
        └───hello-flake: package 'hello-flake-20230218'

As you can see, forAllSystems basically prefixes anything in the passed attrset with <system>.

As the linked issue notes, the modern equivalent to defaultPackage.<system> is packages.<system>.default. So the necessary change is as simple as:

diff --git a/flake.nix b/flake.nix
index c0d02ed..31c42c9 100644
--- a/flake.nix
+++ b/flake.nix
@@ -52,13 +52,9 @@
 
       # Provide some binary packages for selected system types.
       packages = forAllSystems (system:
-        {
+        rec {
           inherit (nixpkgsFor.${system}) hello-flake;
+          default = hello-flake;
         });
-
-      # The default package for 'nix build'. This makes sense if the
-      # flake provides only one package or there is a clear "main"
-      # package.
-      defaultPackage = forAllSystems (system: self.packages.${system}.hello-flake);
     };
 }

By the way, be sure to update the nixpkgs input to a newer version: 21.05 has been unsupported for quite some time now.

2 Likes