Nix Language

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

Basic

# Single-line comment
/* Multi-line
   comment */
# Simple value bindings
let
  x = 10;
  y = x + 5;
in
  y

Data Types

Literals

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

Paths

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

Expressions

Let-in

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

If-then-else

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

With

Used to import variables into scope.

with builtins; head [1 2 3]

Collections

Lists

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

Add to list:

newList = listExample ++ [ "other" ];

Sets (like dictionaries/maps)

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

Access:

person.name  # => "Alice"

Nested sets:

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

Merge/Override sets:

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

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)

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):

{ a, b ? 5 }: a + b

Operators

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

Example:

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

Builtins

Nix comes with many built-in functions.

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:

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

Imports

import ./file.nix

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

Recursion

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