Derivations

Build instructions for Nix packages expressed using the Nix language

Concepts / Derivations

A derivation is an instruction that Nix uses to realise a Nix package. They're created using a special derivation function in the Nix language. They can depend on any number of other derivations and produce one or more final outputs. A derivation and all of the dependencies required to build it—direct dependencies, and all dependencies of those dependencies, etc—is called a closure.

Derivation outputs

The most common outputs:

  • out, the most generic one
  • lib, for library outputs
  • dev, general development resources such as header files
  • man, for manual pages

A derivation and all of the dependencies required to build it—direct dependencies, and all dependencies of those dependencies, etc—is called a package closure.

Mental model

You may find it helpful to think of a derivation as the plan or blueprint for a Nix package.

Derivations in the Nix language

In the Nix language, derivations are created using the derivation function. Here's the type signature for derivation expressed as a Haskell-ish signature:1

derivation ::
    { system   : String
    , name     : String
    , builder  : Path | Derivation
    , ?args    : [String]
    , ?outputs : [String]
    } -> Derivation

Here's an example derivation:

derivation {
  # A name for the derivation (whatever you choose)
  name = "hello-text";
  # The system realising the derivation
  system = "x86_64-linux";
  # The program realising the derivation
  builder = "bash";
  # Arguments passed to the builder program
  args = ["-c" "mkdir $out && echo Hello world > $out/hello.txt"]
};

And that's it! The derivation function takes only these arguments. But derivations can be far less straightforward, because the scripting logic that you pass via args can be arbitrarily complex.

String interpolation

If Nix sees this string...

buildPhase = ''
  mv ${pkgs.website}/favicon.ico
'';

The string output of a derivation is always a Nix store path

Derivation outputs

Realisation

Special variables

There are two special variables to be aware of when writing derivations:

  • $out represents the root of the directory structure for build output.
  • $src represents the build sources.

The standard environment

Most derivations in the Nix ecosystem are based on the mkDerivation function from the standard environment

While you can create derivations using the raw derivation function, it's far more common to use a wrapper function around it. Perhaps the most commonly used wrapper function is stdenv.mkDerivation. Arguments:

  • The name of the package. If you specify pname and version instead, the name ends up ${pname}-${version}.

Other derivation functions

Outside of stdenv.mkDerivation, there are many custom derivation wrappers for specific languages, frameworks, and more (and many of those actually wrap stdenv.mkDerivation). Some examples:

You're likely to encounter many more in the Nix ecosystem. And you're always free to create your own derivation functions and even wrap helper functions like buildPythonApplication.

Footnotes

  1. Kudos to Ian Henry for this idea.


Was this page helpful?