Primitives & Basic Types
# Strings
"hello world"
''
Multi-line strings (indentation is stripped).
Useful for scripts and configs.
''
"Interpolation: ${pkgName}-${version}"
# Numbers
42
3.14
# Booleans & null
true false null
# Paths (resolved relative to the file)
./src/main.rs # relative path
/etc/nixos # absolute path
<nixpkgs> # search path (NIX_PATH)
Attribute Sets (attrsets)
The fundamental data structure — think JSON objects or Python dicts.
# Basic attrset
{
name = "my-package";
version = "1.0.0";
meta = {
license = "MIT";
};
}
# Recursive attrset (self-referencing)
rec {
x = 1;
y = x + 1; # y = 2
}
# Access attributes
mySet.name # "my-package"
mySet.meta.license # "MIT"
mySet.missing or "default" # with fallback
# Merge attrsets
{ a = 1; } // { b = 2; } # { a = 1; b = 2; }
{ a = 1; } // { a = 9; } # { a = 9; } (right wins)
# Check membership
mySet ? name # true
let / in & with
# let bindings introduce local scope
let
name = "hello";
version = "2.12";
in
"${name}-${version}" # "hello-2.12"
# with brings an attrset's attrs into scope
with pkgs; [
git
ripgrep
fd
]
# equivalent to [ pkgs.git pkgs.ripgrep pkgs.fd ]
Functions
# Single-argument function (lambda)
x: x + 1
# Multi-argument (curried)
x: y: x + y
# Attrset pattern (destructuring)
{ name, version, ... }:
"${name}-${version}"
# With default values
{ name, version ? "0.0.0", ... }:
"${name}-${version}"
# Bind the whole set too
{ name, ... } @ args:
args // { wrapped = true; }
# Named function (just a binding)
let
add = a: b: a + b;
in
add 3 4 # 7
Lists & Conditionals
# Lists (heterogeneous, whitespace-separated)
[ 1 "two" true ./path { a = 3; } ]
# Concatenation
[ 1 2 ] ++ [ 3 4 ] # [ 1 2 3 4 ]
# Conditionals
if x > 0 then "positive" else "non-positive"
# assert (fails evaluation if false)
assert builtins.pathExists ./flake.nix;
"flake exists"
Imports & Built-ins
# Import another .nix file (evaluates it)
import ./lib.nix
# Import with arguments
import ./package.nix { inherit pkgs; }
# Useful builtins
builtins.map (x: x * 2) [ 1 2 3 ] # [ 2 4 6 ]
builtins.filter (x: x > 2) [ 1 2 3 4 ] # [ 3 4 ]
builtins.attrNames { a = 1; b = 2; } # [ "a" "b" ]
builtins.length [ 1 2 3 ] # 3
builtins.readFile ./README.md
builtins.toJSON { hello = "world"; }
builtins.fetchurl { url = "..."; sha256 = "..."; }
# inherit (shorthand for attr = attr)
let x = 1; y = 2;
in { inherit x y; } # { x = 1; y = 2; }
# inherit from another set
{ inherit (pkgs) git ripgrep; }