1# Option Definitions {#sec-option-definitions}
2
3Option definitions are generally straight-forward bindings of values to
4option names, like
5
6```nix
7config = {
8 services.httpd.enable = true;
9};
10```
11
12However, sometimes you need to wrap an option definition or set of
13option definitions in a *property* to achieve certain effects:
14
15## Delaying Conditionals {#sec-option-definitions-delaying-conditionals}
16
17If a set of option definitions is conditional on the value of another
18option, you may need to use `mkIf`. Consider, for instance:
19
20```nix
21config = if config.services.httpd.enable then {
22 environment.systemPackages = [ ... ];
23 ...
24} else {};
25```
26
27This definition will cause Nix to fail with an "infinite recursion"
28error. Why? Because the value of `config.services.httpd.enable` depends
29on the value being constructed here. After all, you could also write the
30clearly circular and contradictory:
31
32```nix
33config = if config.services.httpd.enable then {
34 services.httpd.enable = false;
35} else {
36 services.httpd.enable = true;
37};
38```
39
40The solution is to write:
41
42```nix
43config = mkIf config.services.httpd.enable {
44 environment.systemPackages = [ ... ];
45 ...
46};
47```
48
49The special function `mkIf` causes the evaluation of the conditional to
50be "pushed down" into the individual definitions, as if you had written:
51
52```nix
53config = {
54 environment.systemPackages = if config.services.httpd.enable then [ ... ] else [];
55 ...
56};
57```
58
59## Setting Priorities {#sec-option-definitions-setting-priorities}
60
61A module can override the definitions of an option in other modules by
62setting an *override priority*. All option definitions that do not have the lowest
63priority value are discarded. By default, option definitions have
64priority 100 and option defaults have priority 1500.
65You can specify an explicit priority by using `mkOverride`, e.g.
66
67```nix
68services.openssh.enable = mkOverride 10 false;
69```
70
71This definition causes all other definitions with priorities above 10 to
72be discarded. The function `mkForce` is equal to `mkOverride 50`, and
73`mkDefault` is equal to `mkOverride 1000`.
74
75## Ordering Definitions {#sec-option-definitions-ordering}
76
77It is also possible to influence the order in which the definitions for an option are
78merged by setting an *order priority* with `mkOrder`. The default order priority is 1000.
79The functions `mkBefore` and `mkAfter` are equal to `mkOrder 500` and `mkOrder 1500`, respectively.
80As an example,
81
82```nix
83hardware.firmware = mkBefore [ myFirmware ];
84```
85
86This definition ensures that `myFirmware` comes before other unordered
87definitions in the final list value of `hardware.firmware`.
88
89Note that this is different from [override priorities](#sec-option-definitions-setting-priorities):
90setting an order does not affect whether the definition is included or not.
91
92## Merging Configurations {#sec-option-definitions-merging}
93
94In conjunction with `mkIf`, it is sometimes useful for a module to
95return multiple sets of option definitions, to be merged together as if
96they were declared in separate modules. This can be done using
97`mkMerge`:
98
99```nix
100config = mkMerge
101 [ # Unconditional stuff.
102 { environment.systemPackages = [ ... ];
103 }
104 # Conditional stuff.
105 (mkIf config.services.bla.enable {
106 environment.systemPackages = [ ... ];
107 })
108 ];
109```