I decide to start learning Nix by reading through the glossary. I don’t expect to fully understand every definition – I expect it will take first-hand experience to really understand these terms – but I think it will be a useful primer before I read the documentation. At least I will recognize when I encounter a Nix-specific term.

Appendix A. Glossary

derivation

A description of a build action. The result of a derivation is a store object. Derivations are typically specified in Nix expressions using the derivation primitive. These are translated into low-level store derivations (implicitly by nix-env and nix-build, or explicitly by nix-instantiate).

This is… the first thing, and also the most confusing thing. I had to break it into multiple sentences.

A description of a build action.

This immediately seems unintuitive to me. Software often has multiple build steps to produce a single artifact. I would call each of these steps a “build action.” But my assumption (and vague memory) is that a derivation is supposed to be “a description of an artifact,” which is to say a description of multiple build actions. So I’m not sure if I am reading that too literally or if Nix has some sort of build system built into it.

The result of a derivation is a store object.

I’m not sure what “result of a derivation” means, but I will assume it means “the result of the build action that the derivation describes.” I don’t love the wording if that is the correct reading.

Derivations are typically specified in Nix expressions using the derivation primitive.

Okay. I suppose I will get to that, when I make my own derivation.

These are translated into low-level store derivations (implicitly by nix-env and nix-build, or explicitly by nix-instantiate).

Okay. I do not know what a “store derivation” is, and this is not defined in the glossary, although the italics imply this is a term of art.

This sentence uses the “old” commands that I am familiar with from using Nix years ago, but I assume now there would be different commands that just use the nix executable.

store

The location in the file system where store objects live. Typically /nix/store.

Okay. That’s sort of a weird usage to me: I would think “store” would mean “the collection of things” not “the location of the collection of things.” The rest of the glossary seems to use this in the intuitive sense, so I assume this is just badly worded.

store path

The location in the file system of a store object, i.e., an immediate child of the Nix store directory.

Okay. Simple enough. Path in the store, not path to the store (which according to the glossary would just be “store,” which I do not believe).

store object

A file that is an immediate child of the Nix store directory. These can be regular files, but also entire directory trees. Store objects can be sources (objects copied from outside of the store), derivation outputs (objects produced by running a build action), or derivations (files describing a build action).

Okay. So derivations can live in the store, build artifacts can live in the store, and plain files can live in the store. Cool. I don’t really understand what it means for a derivation to live in the store, so that’s an open question for me.

substitute

A substitute is a command invocation stored in the Nix database that describes how to build a store object, bypassing the normal build mechanism (i.e., derivations). Typically, the substitute builds the store object by downloading a pre-built version of the store object from some server.

This is the first occurrence of the term “Nix database.” I don’t know what that means. I assume it is separate from the store, but it is not defined anywhere, and descriptions of Nix are usually about “content addressable store” and not “content addressable store plus a database.”

In order to understand Nix, I have to understand what Nix is – how it works, not just how to use it. So I will have to follow up on this.

purity

The assumption that equal Nix derivations when run always produce the same output. This cannot be guaranteed in general (e.g., a builder can rely on external inputs such as the network or the system time) but the Nix model assumes it.

This is a strange thing to define in the glossary since Nix seems to use the word in exactly the way I would expect. But I suppose if you aren’t coming from a functional programming background, the term might not be familiar.

Nix expression

A high-level description of software packages and compositions thereof. Deploying software using Nix entails writing Nix expressions for your packages. Nix expressions are translated to derivations that are stored in the Nix store. These derivations can then be built.

What is a “software package”? Since this is not defined elsewhere in the glossary, I’m going to assume it means the normal thing that it should mean, i.e. “git” or “pcre” would be software packages.

But then what does it mean to compose packages? I don’t know how to compose “git” with anything else. It’s just a package. Packages do not, in my experience, compose with one another.

So maybe the glossary is using “composition” in a different sense. Like, the things that comprise a package. This makes more sense, but that interpretation is grammatically unnatural to me: I would say “software packages and the compositions thereof.” So there’s an open question for me: do packages compose?

Deploying software using Nix entails writing Nix expressions for your packages.

That’s sort of a strange statement. Not building software, but deploying it? That choice of word is strange but I am going to assume it means “using Nix to make software” not literally “using Nix to deploy software.”

Nix expressions are translated to derivations that are stored in the Nix store. These derivations can then be built.

Okay. Expressions become derivations. Derivations are stored in the Nix store.

I assume, based on my prior understanding of the term “expression” and the fact that the definition for derivation says they are created by “expressions using the derivation primitive” that not all expressions become derivations.

reference

A store path P is said to have a reference to a store path Q if the store object at P contains the path Q somewhere. The references of a store path are the set of store paths to which it has a reference.

A derivation can reference other derivations and sources (but not output paths), whereas an output path only references other output paths.

I like that this gives a very precise definition. It’s not completely clear what it means for a store object to “contain” a path – does this mean a symlink to the path from a directory-type object? Or does it mean an occurrence of that path as text in a file? It could be both, I suppose.

reachable

A store path Q is reachable from another store path P if Q is in the closure of the references relation.

Good definition. Intuitive term.

closure

The closure of a store path is the set of store paths that are directly or indirectly “reachable” from that store path; that is, it’s the closure of the path under the references relation. For a package, the closure of its derivation is equivalent to the build-time dependencies, while the closure of its output path is equivalent to its runtime dependencies. For correct deployment it is necessary to deploy whole closures, since otherwise at runtime files could be missing. The command nix-store -qR prints out closures of store paths.

As an example, if the store object at path P contains a reference to path Q, then Q is in the closure of P. Further, if Q references R then R is also in the closure of P.

I have nothing ungenerous to say about this definition. It is clear and concise and gives concrete examples.

For a package, the closure of its derivation is equivalent to the build-time dependencies, while the closure of its output path is equivalent to its runtime dependencies.

Here we see “package” again, and I am going to continue assuming it means what I think it means.

But I highlighted this because of use of the term “output path.” I still don’t quite know how to think about derivations – they’re functions (?) that produce build artifacts – which presumably turn into store objects – and I think “output path” is referring to the path of that store object? Hopefully this will become more clear.

The command nix-store -qR prints out closures of store paths.

Is this still the recommended command? Is there a nix print-closures or something command now?

output path

A store path produced by a derivation.

Oh, there it is. It’s defined. Okay. Okay. Still not… still don’t totally have an intuition for “produced by a derivation.”

deriver

The deriver of an output path is the store derivation that built it.

Okay. Note “store derivation,” not “derivation.” Still unclear on that distinction.

A boring note: this definition links to the defintion of “output path,” which makes it clear that it is a Nix term, but the first occurrence of “output path” in the glossary did not. But none of the definitions I’m copying include these links, so you cannot tell.

validity

A store path is considered valid if it exists in the file system, is listed in the Nix database as being valid, and if all paths in its closure are also valid.

Here we see the Nix database again. This is not a helpful definition: it sort of reads as “a package is valid if it is marked valid,” and I don’t know what it would take to mark something valid, or what it would mean if a package were marked invalid in the database.

user environment

An automatically generated store object that consists of a set of symlinks to “active” applications, i.e., other store paths. These are generated automatically by nix-env.

This gives a hint that “references” probably do include symlinks. Is nix-env still the preferred command to manage the user environment?

profile

A symlink to the current user environment of a user, e.g., /nix/var/nix/profiles/default.

Okay.

NAR

A Nix ARchive. This is a serialisation of a path in the Nix store. It can contain regular files, directories and symbolic links. NARs are generated and unpacked using nix-store --dump and nix-store --restore.

Okay.


This does not define one very important term that I happen to remember: “nixpkgs.” This is the name for, as I recall, the default repository of all packages available in the Nix universe. I remember that you can configure whatever package sources you want – I’m not really sure what the right term for that is – but that is the default, official one.

Nixpkgs is a git repo, and I think contributions to it are just pull requests on GitHub, which I think is neat. Sure, of course, GitHub evil monopoly FUD monolith whatever, but having contributions tied to what is, for better or worse, a developer’s public ID card seems better than signing up for an account on www dot nixos dot org.

Oh, and one more term: channel. I vaguely remember that channels are like… sort of analogous to git remotes? But I only ever had one channel, and it is where nixpkgs came from. I remember doing something with the nix-channel command frequently, even though I only ever had one channel. I think I remember it being analogous to brew update.


So that was helpful, and it left me with some open questions that I will need to follow up on as I learn more:

  • What is the difference between a “derivation” and a “store derivation”?
  • How does a derivation turn into a “result” or an “output path”? When does a derivation “produce” something?
  • What is the Nix database, and what is stored there?
  • What does it mean to compose a package?
  • What are the nix equivalents of nix-env, nix-build, and nix-instantiate?
  • What is the nix equivalent of nix-store -qR to print out the closure of a store path?
  • What are the nix equivalents of nix-store --dump and nix-store --restore, for working with NARs?