Nix Language
3 min read

Nix is a purely functional language used for package management and system configuration.

Basic

nix
# Single-line comment
/* Multi-line
comment */

nix
# Simple value bindings
let
x = 10;
y = x + 5;
in
y

Data Types

Literals

nix
123 # Integer
3.14 # Floating point
"hello" # String
true / false # Boolean
null # Null

Paths

nix
./file.txt # Relative path
/nix/store/... # Absolute Nix path
<nixpkgs> # Nix search path (via -I)

Expressions

Let-in

nix
let
a = 1;
b = 2;
in
a + b

If-then-else

nix
if a > b then "yes" else "no"

With

Used to import variables into scope.

nix
with builtins; head [1 2 3]

Collections

Lists

nix
[1 2 3] # List
listExample = [1 "a" true];

Add to list:

nix
newList = listExample ++ [ "other" ];

Sets (like dictionaries/maps)

nix
{
name = "Alice";
age = 30;
}

Access:

nix
person.name # => "Alice"

Nested sets:

nix
{
user = {
name = "Alice";
age = 30;
};
}

Merge/Override sets:

nix
myset = { a = 3; b = 5; };
overriden = myset // { a = 5; }; # => { a = 5; b = 5; }

combined = myset // { c = 3; }; # => { a = 3; b = 5; c = 3;}

multiple = { a = 3; } // { b = 4; } // { c = 5; };

Functions

Defining functions

nix
x: x + 1 # anonymous function
x: y: x + y # curried (multi-arg) function

# Example usage
addThree = x: x + 3;
result = addThree 2; # => 5

With argument sets (like named parameters)

nix
sumFields = { a, b }: a + b;

# Equivalent to:
# sumFields = args: args.a + args.b

# Calling it
result = sumFields { a = 1; b = 2; }; # => 3

With defaults (default after ? symbol):

nix
{ a, b ? 5 }: a + b

Operators

OperatorMeaning
+ - * /Arithmetic
== !=Equality
`&&`Boolean logic
//Set merge
++List concatenation
?Has attribute
.Attribute access

Example:

nix
{ a = 1; } // { b = 2; } # => { a = 1; b = 2; }
[1 2] ++ [3] # => [1 2 3]

Builtins

Nix comes with many built-in functions.

nix
builtins.length [1 2 3] # => 3
builtins.attrNames { a = 1; b = 2; } # => [ "a" "b" ]
builtins.toString 123 # => "123"

More:

• isString, isList, isAttrs
• map, filter
• elem, head, tail

Use builtins to access them:

nix
builtins.map (x: x + 1) [1 2 3] # => [2 3 4]

Imports

nix
import ./file.nix

Files must evaluate to an expression (often a function or set).

Recursion

nix
rec {
x = 1;
y = x + 2; # x is visible here
}