Package Definitions Explained

2025-05-08

Package Definitions Explained

A package refers to either a collection of files and other data, or a Nix expression representing such a collection before it comes into being. You start by writing a package definition in the Nix language, this definition contains instructions and metadata about the software or artifact you want to "package".

So, the package definition is the blueprint, and the derivation is the detailed plan that Nix follows to build the package. You don't directly get a "package" in the sense of a pre-built artifact until Nix executes the derivation.

The following is a skeleton derivation:

{ stdenv }:

stdenv.mkDerivation { }

A Package Function

The following is a package definition that is a Nix function that will evaluate to a derivation.

# hello.nix
{
  stdenv,
  fetchzip,
}:

stdenv.mkDerivation {
  pname = "hello";
  version = "2.12.1";

  src = fetchzip {
    url = "https://ftp.gnu.org/gnu/hello/hello-2.12.1.tar.gz";
    sha256 = "";
  };
}

The recommended way is to create a default.nix file in the same directory as hello.nix, with the following contents:

# default.nix
let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.05";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in
{
  hello = pkgs.callPackage ./hello.nix { };
}

Now you can run nix-build -A hello to realize the derivation from the package definition in hello.nix.

nix-build -A hello
error: hash mismatch in fixed-output derivation '/nix/store/pd2kiyfa0c06giparlhd1k31bvllypbb-source.drv':
         specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
            got:    sha256-1kJjhtlsAkpNB7f6tZEs+dbKd8z7KoNHyDHEJ0tmhnc=
error: 1 dependencies of derivation '/nix/store/b4mjwlv73nmiqgkdabsdjc4zq9gnma1l-hello-2.12.1.drv' failed to build

Build the Result

./result/bin/hello
Hello, world!

Swaytools Package Definition

The following is the swaytools package definition located at nixpkgs/pkgs/tools/wayland/swaytools/default.nix part of the Nixpkgs collection:

# default.nix
{
  lib,
  setuptools,
  buildPythonApplication,
  fetchFromGitHub,
  slurp,
}:

buildPythonApplication rec {
  pname = "swaytools";
  version = "0.1.2";

  format = "pyproject";

  src = fetchFromGitHub {
    owner = "tmccombs";
    repo = "swaytools";
    rev = version;
    sha256 = "sha256-UoWK53B1DNmKwNLFwJW1ZEm9dwMOvQeO03+RoMl6M0Q=";
  };

  nativeBuildInputs = [ setuptools ];

  propagatedBuildInputs = [ slurp ];

  meta = with lib; {
    homepage = "https://github.com/tmccombs/swaytools";
    description = "Collection of simple tools for sway (and i3)";
    license = licenses.gpl3Only;
    maintainers = with maintainers; [ atila ];
    platforms = platforms.linux;
  };
}
  1. Function Structure:
{ lib, setuptools, buildPythonApplication, fetchFromGitHub, slurp }:
  1. Derivation Creation:
buildPythonApplication rec { ... }
  1. Package Metadata:
pname = "swaytools";
version = "0.1.2";
meta = with lib; {
  homepage = "https://github.com/tmccombs/swaytools";
  description = "Collection of simple tools for sway (and i3)";
  license = licenses.gpl3Only;
  maintainers = with maintainers; [ atila ];
  platforms = platforms.linux;
};
  1. Source Specification:
src = fetchFromGitHub {
  owner = "tmccombs";
  repo = "swaytools";
  rev = version;
  sha256 = "sha256-UoWK53B1DNmKwNLFwJW1ZEm9dwMOvQeO03+RoMl6M0Q=";
};
  1. Build and Runtime Dependencies:
nativeBuildInputs = [ setuptools ];
propagatedBuildInputs = [ slurp ];
  1. Build Format:
# all-packages.nix
swaytools = python3Packages.callPackage ../tools/wayland/swaytools { };

Resources