Skip to content

Apps

Invoking nix run <flake-ref>#<output-name> will actually first look for a <output-name> entry in apps, before looking for a <output-name> entry in packages.

Defining apps entries is useful when a package provides multiple binaries which you want users of your flake to be able to run directly via nix run.

Defining app entries

Each app entry is system-dependent, the key is the output (i.e. the name you will be referring to when using nix run) and the value is an attribute set whose program entry points to the binary to execute:

example - exposing pydoc3 as an app
{
  # flake.nix, https://github.com/nix4plebs/apps-ex
  description = "nix starter flake pinned to 22.11";

  inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; };

  outputs = { self, nixpkgs }:
    let
      allSystems = [
        "x86_64-linux" # AMD/Intel Linux
        "aarch64-linux" # ARM Linux
        "aarch64-darwin" # ARM macOS
      ];

      forAllSystems = fn:
        nixpkgs.lib.genAttrs allSystems
        (system: fn { pkgs = import nixpkgs { inherit system; }; });

    in {
      # used when calling `nix fmt <path/to/flake.nix>`
      formatter = forAllSystems ({ pkgs }: pkgs.nixfmt);

      # nix run|build <flake-ref>#<pkg-name>
      # -- 
      # $ nix run <flake-ref>#hello
      apps = forAllSystems ({ pkgs }: {
        pydoc = {
          type = "app";
          program = "${pkgs.python311}/bin/pydoc3";
        };
      });
    };
}

Note

Struggling to figure out what the program path should be? Add a development shell to your flake, add the package to the environment, enter it and type type <program-name>. The output will be of the form /nix/store/<hash>-<package-name>/path/to/bin. The program path becomes ${pkgs.<package-name>}/path/to/bin.