Nix
Nix
is a functional programming language and Nix-Cli(aka nix)
is a declarative package manager designed to create reproducible and declarative software environments. It works by treating configurations as code, ensuring that every aspect of your environment is consistent, version-controlled, and isolated. One of Nix’s standout features is its ability to manage software dependencies seamlessly while maintaining exact version control.
Key Concepts of Nix
-
Declarative Configurations: Environments and configurations are defined in .nix files, making them reproducible.
-
Immutable Packages: Nix stores packages in a unique, hashed location
/nix/store/$hash-$packagename
, ensuring no conflicts between versions where$hash
represents the hash id of the package and$packagename
refers to the name of the package itself. For example, if I do the follwing in my terminal:$ nix-shell -p gcc
Nix would go and evaluate the package derivation from nixpkgs and store it in
/nix/store/xzfmarrq8x8s4ivpya24rrndqsq2ndiz-gcc-13.3.0
NOTE:
/nix/store
is an immutable file-system which means the user can only access it read-only. -
Version Locking: Using tools like
flakes
ornixpkgs
, you can pin specific versions of packages for consistent builds.
What is nixpkgs?
nixpkgs
is a central repository that contains thousands of software packages available in Nix. It acts as the foundation for most Nix-based configurations and is continuously updated to include new packages and fixes. You can view the repo in GitHub.
$ nix-shell -p neovim git
This command starts a bash
shell environment with neovim and git installed, without affecting your system configuration.
What is flakes?
Flakes are an experimental feature that enhances reproducibility by locking dependencies and configurations in a standardized format. It is intended to replace default.nix
which you would normally use in a Nix system. This brings a new schema where you can define your packages from the web in inputs
and build package or a shell for the user. You could say that flakes work similar to the Rust package manager cargo
or Javascript package manager npm
which locks your dependencies in a separate file (Cargo.lock
and packages-lock.json
respectively), flake.lock
in this case.
# flake.nix
{
description = "An example NixOS configuration";
inputs = {
nixpkgs = { url = "github:nixos/nixpkgs/nixos-unstable"; };
nur = { url = "github:nix-community/NUR"; };
};
outputs = inputs: {
nixosConfigurations = {
mysystem = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [ ./configuration.nix ];
specialArgs = { inherit inputs; };
};
};
};
}
This allow user to use flakes
to build a system configuration using nixosConfigurations
defined in the flake.nix
.
You can learn more about nix and flakes by referring to resources