~/ ~/documents ~/pictures ~/harmful.txt github

Why Nix?

Guaranteeing software is reproducible and secure is vital for:

Reproducibility can be defined as:

Security can be defined as:

Nix helps guarantee that software is both reproducible and secure.

Stemming from the concept that FHS paths are fundamentally not reproducible. Paths such as /bin/python provide little-to-no information about the software that is being run:

One solution commonly used are tools such as Docker or Snap, etc., that create isolated FHS environments containing a specific version along with its dependencies. However, there is no guarantee you will get expected build artifacts from build instructions, as putting all the build artifacts in an isolated container only guarantees consistency, never reproducibility. During the build phase, tools from the host’s FHS are often used, file fetches are made, and the dependencies that come from other isolated environments cannot be guaranteed to be the same. For example, two machines using the same container image will always get the same results, but two machines building the same container using a Dockerfile can never guarantee the same results.

Nix first computes its derivation (this is usually done by evaluating expressions written in Nix language) for every package before building. This includes:

Example

For example, here are the outputs of the GNU Hello package (some fields have been omitted for brevity):

{
  "/nix/store/sg3sw1zdddfkl3hk639asml56xsxw8pf-hello-2.10.drv": {
    "outputs": {
      "out": {
        "path": "/nix/store/dvv4irwgdm8lpbhdkqghvmjmjknrikh4-hello-2.10"
      }
    },
    "inputSrcs": ["/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],
    "inputDrvs": {
      "/nix/store/8pq31sp946581sbh2m18pb8iwp0bwxj6-stdenv-linux.drv": ["out"],
      "/nix/store/cni8m2cjshnc8fbanwrxagan6f8lxjf6-hello-2.10.tar.gz.drv": ["out"],
      "/nix/store/md39vwk6mmi64f6z6z9cnnjksvv6xkf3-bash-4.4-p23.drv": ["out"]
    },
    "platform": "x86_64-linux",
    "builder": "/nix/store/kgp3vq8l9yb8mzghbw83kyr3f26yqvsz-bash-4.4-p23/bin/bash",
    "args": ["-e", "/nix/store/9krlzvny65gdc8s7kpb6lkx8cd02c25b-default-builder.sh"],
    "env": {
      "buildInputs": "",
      "builder": "/nix/store/kgp3vq8l9yb8mzghbw83kyr3f26yqvsz-bash-4.4-p23/bin/bash",
      "doCheck": "1",
      "name": "hello-2.10",
      "nativeBuildInputs": "",
      "out": "/nix/store/dvv4irwgdm8lpbhdkqghvmjmjknrikh4-hello-2.10",
      "outputs": "out",
      "pname": "hello",
      "src": "/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz",
      "stdenv": "/nix/store/hn7xq448b49d40zq0xs6lq538qvldls1-stdenv-linux",
      "system": "x86_64-linux",
      "version": "2.10"
    }
  }
}

Nix then realizes the derivation by running the build instructions specified in an isolated environment. Packages built with Nix can guarantee that the same inputs will always produce the same outputs (outputs can still differ if build instructions make use of hardware-dependent information such as current time, etc.).

This provides the following benefits: