Introduction The problem space Nix is a system for controlling the automatic creation and distribution of data, such as computer programs and other software artifacts. This is a very general problem, and there are many applications that fall under this description. Build management Build management tools are used to perform software builds, that is, the construction of derived products (derivates)) such as executable programs from source code. A commonly used build tool is Make, which is a standard tool on Unix systems. These tools have to deal with several issues: Efficiency. Since building large systems can take a substantial amount of time, it is desirable that build steps that have been performed in the past are not repeated unnecessarily, i.e., if a new build differs from a previous build only with respect to certain sources, then only the build steps that (directly or indirectly) depend on those sources should be redone. Correctness is this context means that the derivates produced by a build are always consistent with the sources, that is, they are equal to what we would get if we were to build the derivates from those sources. This requirement is trivially met when we do a full, unconditional build, but is far from trivial under the requirement of efficiency, since it is not easy to determine which derivates are affected by a change to a source. Variability is the property that a software system can be built in a (potentially large) number of variants. Variation exists both in time---the evolution of different versions of an artifact---and in space---the artifact might have configuration options that lead to variants that differ in the features they support (for example, a system might be built with or without debugging information). Build managers historically have had good support for variation in time (rebuilding the system in an intelligent way when sources change is one of the primary reasons to use a build manager), but not always for variation in space. For example, make will not automatically ensure that variant builds are properly isolated from each other (they will in fact overwrite each other unless special precautions are taken). High-level system modelling language. The language in which one describes what and how derivates are to be produced should have sufficient abstraction facilities to make it easy to specify the derivation of even very large systems. Also, the language should be modular to enable components from possible different sources to be easily combined. Package management After software has been built, is must also be deployed in the intended target environment, e.g., the user's workstation. Examples include the Red Hat package manager (RPM), Microsoft's MSI, and so on. Here also we have several issues to contend with: The creation of packages from some formal description of what artifacts should be distributed in the package. The deployment of packages, that is, the mechanism by which we get them onto the intended target environment. This can be as simple as copying a file, but complexity comes from the wide range of possible installation media (such as a network install), and the scalability of the process (if a program must be installed on a thousand systems, we do not want to visit each system and perform some manual steps to install the program on that system; that is, the complexity for the system administrator should be constant, not linear). What Nix provides Here is a summary of Nix's main features: Reliable dependencies. Builds of file system objects depend on other file system object, such as source files, tools, and so on. We would like to ensure that a build does not refer to any objects that have not been declared as inputs for that build. This is important for several reasons. First, if any of the inputs change, we need to rebuild the things that depend on them to maintain consistency between sources and derivates. Second, when we deploy file system objects (that is, copy them to a different system), we want to be certain that we copy everything that we need. Nix ensures this by building and storing file system objects in paths that are infeasible to predict in advance. For example, the artifacts of a package X might be stored in /nix/store/d58a0606ed616820de291d594602665d-X, rather than in, say, /usr/lib. The path component d58a... is actually a cryptographic hash of all the inputs (i.e., sources, requisites, and build flags) used in building X, and as such is very fragile: any change to the inputs will change the hash. Therefore it is not sensible to hard-code such a path into the build scripts of a package Y that uses X (as does happen with fixed paths such as /usr/lib). Rather, the build script of package Y is parameterised with the actual location of X, which is supplied by the Nix system. Support for variability. As stated above, the path name of a file system object contain a cryptographic hash of all inputs involved in building it. A change to any of the inputs will cause the hash to change--and by extension, the path name. These inputs include both sources (variation in time) and configuration options (variation in space). Therefore variants of the same package don't clash---they can co-exist peacefully within the same file system. So thanks to Nix's mechanism for reliably dealing with dependencies, we obtain management of variants for free (or, to quote Simon Peyton-Jone, it's not free, but it has already been paid for). Transparent source/binary deployment. Easy configuration duplication. Automatic storage management. Atomic upgrades and rollbacks. Support for many simultaneous configurations. Portability. Nix is quite portable. Contrary to build systems like those in, e.g., Vesta and ClearCase [sic?], it does not rely on operating system extensions. Here is what Nix doesn't yet provide, but will: Build management. In principle it is already possible to do build management using Fix (by writing builders that perform appropriate build steps), but the Fix language is not yet powerful enough to make this pleasant. The Maak build manager should be retargeted to produce Nix expressions, or alternatively, extend Fix with Maak's semantics and concrete syntax (since Fix needs a concrete syntax anyway). Another interesting idea is to write a make implementation that uses Nix as a back-end to support legacy build files. The Nix system ... Existing tools in this field generally both a underlying model (such as the derivation graph of build tools, or the versioning scheme that determines when two packages are compatible in a package management system) and a formalism that allows ... Following the principle of separation of mechanism and policy, the Nix system separates the low-level aspect of file system object management form the high-level aspect of the ...