The Nix language is designed for conveniently creating and composing derivations – precise descriptions of how contents of existing files are used to derive new files. It is a domain-specific, purely functional, lazily evaluated, dynamically typed programming language.
You may quickly encounter Nix language expressions that look very complicated. As with any programming language, the required amount of Nix language code closely matches the complexity of the problem it is supposed to solve, and reflects how well the problem – and its solution – is understood. Building software is a complex undertaking, and Nix both exposes and allows managing this complexity with the Nix language.
Yet, the Nix language itself has only few basic concepts that will be introduced in this tutorial, and which can be combined arbitrarily. What may look complicated comes not from the language, but from how it is used.
Overview
This is an introduction to reading the Nix language, for the purpose of following other tutorials and examples.
Using the Nix language in practice entails multiple things:
- Language: syntax and semantics
- Libraries: builtins and pkgs.lib
- Developer tools: testing, debugging, linting, formatting, …
- Generic build mechanisms: stdenv.mkDerivation, trivial builders, …
- Composition and configuration mechanisms: override, overrideAttrs, overlays, callPackage, …
- Ecosystem-specific packaging mechanisms: buildGoModule, buildPythonApplication, …
- NixOS module system: config, option, …
This tutorial only covers the most important language features, briefly discusses libraries, and at the end will direct you to reference material and resources on the other components.