What is Nix?
Package manager
Programming Language
Os
Package repository
We are going to focus on mainly on the package manager part.
Ok so how is Nix different from other package managers??
Nix is trying to stay as pure and reproducible as possible.
How Nix works?
FHS: Peeking behind the curtain
								
									# ls /bin
									sh
								
							
								
									# ls /lib
									ls: cannot access '/lib': No such file or
									directory
								
							
								
									# ls /usr/bin
									env
								
							
Huh??
								
									# ls /nix/store

									zzfarkcyb4v11ai1kbk3mdh2y7jalbiq-CVE-2017-8372-CVE-2017-8373.patch.drv
									zzfkkrvn1f4ks46z22rxbhnxg8mmj4bp-python3.10-sphinxcontrib-jsmath-1.0.1.drv
									zzflbnwmr19w0b5vsvf90292bszkbqx4-patchelf-0.15.0.drv
									zzi69bi53biq6zckij6cfwcjggqskbb2-asdf-3.3.6.tar.gz.drv
									zznxvgy5pi4ny9dpl5gkxk9y5i1k436h-wayland-1.22.0.drv
									zzpm91md3wqllaqpzm7whvcpafblcp3d-0007-qtbase-find-tools-in-PATH.patch
									zzrgf0qw8vd3rd3fznzif1fh5k856rdy-libass-0.17.1/
									zzwsixlsccw8vdy6wb9qqzj1fmyjis3n-net-tools-2.10/
									zzxszlz0zj3054j087h0a87vg9chr6vl-foldl-1.4.14-r2.cabal.drv
									zzyy4xm6m2vdqi0h0c0dgr75jl8s0n3b-source.drv
									....
								
							
RPath
						
							$ patchelf --print-rpath
							/nix/store/ffll6glz3gwx342z0ch8wx30p5cnqz1z-python3-3.11.5/bin/python

							/nix/store/ffll6glz3gwx342z0ch8wx30p5cnqz1z-python3-3.11.5/lib:/nix/store/gqghjch4p1s69sv4mcjksb2kb65rwqjy-glibc-2.38-23/lib:/nix/store/9fy9zzhf613xp0c3jsjxbjq6yp8afrsv-gcc-12.3.0-lib/lib
						
					
Dependencies
Compile-time Explicitly listed
Runtime Hashes of other paths that exist in a path
Derivation: Sandboxed Builds
The build sees:

  • Paths referenced by its derivation
  • That's it...
What's a derivation?
						
							builtins.derivation {
							  name = "mybuild";
							  builder = "${pkgs.python}/bin/python";
							  args = [ "${./script.py}" ];
							  system = "x86_64-linux";

							  # Optional additional environment
							  PATH="...";
							  ENV="...";
							}
						
					
Where do I output the build?



Just another variable called
$out


Determined by hashing the derivation iteslf
How does source code get on the machine though?
Fixed-output Derivation:
						
							builtins.derivation {
							  name = "mybuild";
							  builder = "${pkgs.python}/bin/python";
							  args = [ "${./script.py}" ];
							  system = "x86_64-linux";
						
					
						
							  outputHashAlgo = "sha256";
							  outputHash = "...";
							}
						
					
The build sees:

  • Paths referenced by its derivation
  • That's it...
  • The Internet
In practice:
Why is this awesome?

  • Reproducible, even across machines
  • Trivial to offload
  • You can be sure what's in a package
  • Trivial to distribute builds
Quick demo
Nix Language
Nix Concepts:

Functional

Programming style based on mathematical functions.
Instead of writing a sequence of operations that should be executed.
You apply functions to input to generate ouput.
							
								names = ['Mary', 'Isla', 'Sam']

								# Procedural
								for i in range(len(names)):
								   names[i] = hash(names[i])

								# Functional
								names = map(hash, names)
							
						
							
								let
								  names = [ "Mary" "Isla" "Sam" ];
								in builtins.map (x: builtins.hashString "sha256" x)	names
							
						
							
								let
								  names = [ "Mary" "Isla" "Sam" ];
								in builtins.map (builtins.hashString "sha256") names
								# With currying
							
						

Pure

A pure function is a function where the return value is only determined by its inputs.
In Nix, all build operations try to be as pure as possible to achieve reproducible builds.
Nix reproducibility statistics.

Lazy

Expressions are only evaluated when their value is needed (used).
						
							let
							  a = abort "will never happen";
							  b = "hello";
							  c = "world";
							in b + c
						
					
Nix Flakes
Flakes introduce a dependecy managing system that improves reproducibility and usability in the nix ecosystem.
Although it's still an experimental feature, flakes are widely used in the Nix community.

Top level attributes:

description is a string describing the flake.
inputs is an attribute set of all the dependencies of the flake.
outputs is a function that takes an attribute set of all inputs, and outputs another attribute set.
nixConfig attribute set which reflect the values given to nix.conf.

Inputs

All the inputs get automatically fetched and evaluated as a flakes. If you want non flake project as an input you can specify `flake = false;`
							
								inputs.import-cargo = {
								  type = "github";
								  owner = "edolstra";
								  repo = "import-cargo";
								};
								# or
								inputs.import-cargo.url = "github:edolstra/import-cargo";
							
						

Where is the reproducibility tho?

The lock file!

Lock file

flake.nix are typically "unlocked" (they do NOT specify version/commit), that's why we need the flake.lock file that is generated by nix.
The generated lock file contains a graph structure specifying the exact version (commit) and hash of the input. To ensure reproducibility.
						
                          "version": 7,
                          "root": "n1",
                          "nodes": {
                            "n1": {
                              "inputs": {
                                "nixpkgs": "n2",
                                "import-cargo": "n3",
                                "grcov": "n4"
                              }
                            },
                            "n2": {
                              "inputs": {},
                              "locked": {
                                "owner": "edolstra",
                                "repo": "nixpkgs",
                                "rev": "7f8d4b088e2df7fdb6b513bc2d6941f1d422a013",
                                "type": "github",
                                "lastModified": 1580555482,
                                "narHash": "sha256-OnpEWzNxF/AU4KlqBXM2s5PWvfI5/BS6xQrPvkF5tO8="
                              },
                              "original": {
                                "id": "nixpkgs",
                                "type": "indirect"
                              }
                            },
                            "n3": {
                              "inputs": {},
                              "locked": {
                                "owner": "edolstra",
                                "repo": "import-cargo",
                                "rev": "8abf7b3a8cbe1c8a885391f826357a74d382a422",
                                "type": "github",
                                "lastModified": 1567183309,
                                "narHash": "sha256-wIXWOpX9rRjK5NDsL6WzuuBJl2R0kUCnlpZUrASykSc="
                              },
                              "original": {
                                "owner": "edolstra",
                                "repo": "import-cargo",
                                "type": "github"
                              }
                            },
                            "n4": {
                              "inputs": {},
                              "locked": {
                                "owner": "mozilla",
                                "repo": "grcov",
                                "rev": "989a84bb29e95e392589c4e73c29189fd69a1d4e",
                                "type": "github",
                                "lastModified": 1580729070,
                                "narHash": "sha256-235uMxYlHxJ5y92EXZWAYEsEb6mm+b069GAd+BOIOxI="
                              },
                              "original": {
                                "owner": "mozilla",
                                "repo": "grcov",
                                "type": "github"
                              },
                              "flake": false
                            }
                          }
                        }
						
					
Flake resolution
Flake URL-syntax
						
							nix run github:hyprwm/Hyprland
							nix run sourcehut:~michal_atlas/nur-packages#mystic
							nix flake show github:dev-null-undefined/ascii-art

							# Generic version
							nix flake show git+https://github.com/hyprwm/Hyprland
						
					
						
							# Without type
							$ nix run foobar#example
							error: cannot find flake 'flake:foobar' in the flake registries

							# Same thing:
							nix flake show flake:gemini
							nix flake show gemini
						
					
						
                            {
                              "flakes": [
                                {
                                  "from": {
                                    "id": "agda",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "agda",
                                    "repo": "agda",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "arion",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "hercules-ci",
                                    "repo": "arion",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "blender-bin",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "dir": "blender",
                                    "owner": "edolstra",
                                    "repo": "nix-warez",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "cachix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "cachix",
                                    "repo": "cachix",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "composable",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "ComposableFi",
                                    "repo": "composable",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "disko",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "disko",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "dreampkgs",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "dreampkgs",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "dwarffs",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "edolstra",
                                    "repo": "dwarffs",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "emacs-overlay",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "emacs-overlay",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "fenix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "fenix",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "flake-parts",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "hercules-ci",
                                    "repo": "flake-parts",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "flake-utils",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "numtide",
                                    "repo": "flake-utils",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "gemini",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "flake-gemini",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "hercules-ci-effects",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "hercules-ci",
                                    "repo": "hercules-ci-effects",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "hercules-ci-agent",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "hercules-ci",
                                    "repo": "hercules-ci-agent",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "home-manager",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "home-manager",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "hydra",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "hydra",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "mach-nix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "DavHau",
                                    "repo": "mach-nix",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nimble",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "flake-nimble",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "nix",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nix-darwin",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "LnL7",
                                    "repo": "nix-darwin",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nixops",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "nixops",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nixos-hardware",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "nixos-hardware",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nixos-homepage",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "nixos-homepage",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nixos-search",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "nixos-search",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nur",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "NUR",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nixpkgs",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "ref": "nixpkgs-unstable",
                                    "repo": "nixpkgs",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "templates",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "templates",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "patchelf",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "patchelf",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "poetry2nix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-community",
                                    "repo": "poetry2nix",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nix-serve",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "edolstra",
                                    "repo": "nix-serve",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "nickel",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "tweag",
                                    "repo": "nickel",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "bundlers",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "NixOS",
                                    "repo": "bundlers",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "pridefetch",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "SpyHoodle",
                                    "repo": "pridefetch",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "systems",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "nix-systems",
                                    "repo": "default",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "helix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "helix-editor",
                                    "repo": "helix",
                                    "type": "github"
                                  }
                                },
                                {
                                  "from": {
                                    "id": "sops-nix",
                                    "type": "indirect"
                                  },
                                  "to": {
                                    "owner": "Mic92",
                                    "repo": "sops-nix",
                                    "type": "github"
                                  }
                                }
                              ],
                              "version": 2
                            }
						
					
Flake Outputs
Development environments: Demo
						
{
  inputs = {
    nixpkgs = {
      url = "github:NixOS/nixpkgs";
    };
  };

  outputs = {nixpkgs, ...}: let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    devShells = {
      x86_64-linux = {
        default = pkgs.mkShell {
          nativeBuildInputs = [
            pkgs.python3
            pkgs.nixfmt
            (pkgs.writeShellScriptBin "foobar" ''
              echo 'Welcome to the FIT Nix meetup'
            '')
            (pkgs.writeShellScriptBin "my-old-python" ''
              ${pkgs.python38}/bin/python "$@"
            '')
            pkgs.hello.nativeBuildInputs
          ];
        };
      };
    };
  };
}
						
					
						
{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs";

  outputs = {nixpkgs, ...}: let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    devShells.x86_64-linux.default = pkgs.mkShell {
      nativeBuildInputs = [
        pkgs.python3
        pkgs.nixfmt
        (pkgs.writeShellScriptBin "foobar" ''
          echo 'Welcome to the FIT Nix meetup'
        '')
        (pkgs.writeShellScriptBin "my-old-python" ''
          ${pkgs.python38}/bin/python "$@"
        '')
        pkgs.hello.nativeBuildInputs
      ];
    };
  };
}
						
					
						
{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs";

  outputs = {nixpkgs, ...}: let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    devShells.x86_64-linux.default = pkgs.mkShell with pkgs; {
      nativeBuildInputs = [
        python3
        nixfmt
        (writeShellScriptBin "foobar" ''
          echo 'Welcome to the FIT Nix meetup'
        '')
        (writeShellScriptBin "my-old-python" ''
          ${pkgs.python38}/bin/python "$@"
        '')
        hello.nativeBuildInputs
      ];
    };
  };
}
						
					
						
{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs";

  outputs = {nixpkgs, ...}: let
    system = "x86_64-linux";
    pkgs = nixpkgs.legacyPackages.${system};
  in {
	devShells.${system}.default = pkgs.mkShell with pkgs; {
      nativeBuildInputs = [
        python3
        nixfmt
        (writeShellScriptBin "foobar" ''
          echo 'Welcome to the FIT Nix meetup'
        '')
        (writeShellScriptBin "my-old-python" ''
          ${pkgs.python38}/bin/python "$@"
        '')
        hello.nativeBuildInputs
      ];
    };
  };
}
						
					
Declaring your own package: Demo
Usefull tools
https://github.com/utdemir/nix-tree
https://github.com/kamadorueda/alejandra
https://github.com/maralorn/nix-output-monitor
https://github.com/nix-community/comma
https://github.com/Gabriella439/nix-diff
Projects that use Nix
https://github.com/engineer-man/piston
https://replit.com/
https://github.com/facebook/hhvm
https://github.com/hyprwm/Hyprland
https://github.com/iovisor/bpftrace
https://github.com/tailscale/tailscale
https://github.com/PolyMC/PolyMC
https://github.com/rust-lang/rustlings
https://github.com/cachix/cachix
https://github.com/direnv/direnv
https://github.com/helix-editor/helix
https://github.com/haskell/haskell-language-server
https://github.com/juanfont/headscale
https://github.com/CatalaLang/catala