1 # Option Declarations {#sec-option-declarations}
3 An option declaration specifies the name, type and description of a
4 NixOS configuration option. It is invalid to define an option that
5 hasn't been declared in any module. An option declaration generally
12 type = type specification;
13 default = default value;
14 example = example value;
15 description = "Description for use in the NixOS manual.";
21 The attribute names within the `name` attribute path must be camel
22 cased in general but should, as an exception, match the [ package
23 attribute name](https://nixos.org/nixpkgs/manual/#sec-package-naming)
24 when referencing a Nixpkgs package. For example, the option
25 `services.nix-serve.bindAddress` references the `nix-serve` Nixpkgs
28 The function `mkOption` accepts the following arguments.
32 : The type of the option (see [](#sec-option-types)). This
33 argument is mandatory for nixpkgs modules. Setting this is highly
34 recommended for the sake of documentation and type checking. In case it is
35 not set, a fallback type with unspecified behavior is used.
39 : The default value used if no value is defined by any module. A
40 default is not required; but if a default is not given, then users
41 of the module will have to define the value of the option, otherwise
42 an error will be thrown.
46 : A textual representation of the default value to be rendered verbatim in
47 the manual. Useful if the default value is a complex expression or depends
48 on other values or packages.
49 Use `lib.literalExpression` for a Nix expression, `lib.literalMD` for
50 a plain English description in [Nixpkgs-flavored Markdown](
51 https://nixos.org/nixpkgs/manual/#sec-contributing-markup) format.
55 : An example value that will be shown in the NixOS manual.
56 You can use `lib.literalExpression` and `lib.literalMD` in the same way
61 : A textual description of the option in [Nixpkgs-flavored Markdown](
62 https://nixos.org/nixpkgs/manual/#sec-contributing-markup) format that will be
63 included in the NixOS manual.
65 ## Utility functions for common option patterns {#sec-option-declarations-util}
67 ### `mkEnableOption` {#sec-option-declarations-util-mkEnableOption}
69 Creates an Option attribute set for a boolean value option i.e an
70 option to be toggled on or off.
72 This function takes a single string argument, the name of the thing to be toggled.
74 The option's description is "Whether to enable \<name\>.".
78 ::: {#ex-options-declarations-util-mkEnableOption-magic .example}
79 ### `mkEnableOption` usage
81 lib.mkEnableOption "magic"
84 type = lib.types.bool;
87 description = "Whether to enable magic.";
92 ### `mkPackageOption` {#sec-option-declarations-util-mkPackageOption}
97 mkPackageOption pkgs "name" { default = [ "path" "in" "pkgs" ]; example = "literal example"; }
100 Creates an Option attribute set for an option that specifies the package a module should use for some purpose.
102 **Note**: You shouldn’t necessarily make package options for all of your modules. You can always overwrite a specific package throughout nixpkgs by using [nixpkgs overlays](https://nixos.org/manual/nixpkgs/stable/#chap-overlays).
104 The package is specified in the third argument under `default` as a list of strings
105 representing its attribute path in nixpkgs (or another package set).
106 Because of this, you need to pass nixpkgs itself (or a subset) as the first argument.
108 The second argument may be either a string or a list of strings.
109 It provides the display name of the package in the description of the generated option
110 (using only the last element if the passed value is a list)
111 and serves as the fallback value for the `default` argument.
113 To include extra information in the description, pass `extraDescription` to
114 append arbitrary text to the generated description.
115 You can also pass an `example` value, either a literal string or an attribute path.
117 The default argument can be omitted if the provided name is
118 an attribute of pkgs (if name is a string) or a
119 valid attribute path in pkgs (if name is a list).
121 If you wish to explicitly provide no default, pass `null` as `default`.
123 []{#ex-options-declarations-util-mkPackageOption}
126 ::: {#ex-options-declarations-util-mkPackageOption-hello .example}
127 ### Simple `mkPackageOption` usage
129 lib.mkPackageOption pkgs "hello" { }
132 type = lib.types.package;
133 default = pkgs.hello;
134 defaultText = lib.literalExpression "pkgs.hello";
135 description = "The hello package to use.";
140 ::: {#ex-options-declarations-util-mkPackageOption-ghc .example}
141 ### `mkPackageOption` with explicit default and example
143 lib.mkPackageOption pkgs "GHC" {
145 example = "pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])";
149 type = lib.types.package;
151 defaultText = lib.literalExpression "pkgs.ghc";
152 example = lib.literalExpression "pkgs.haskell.packages.ghc92.ghc.withPackages (hkgs: [ hkgs.primes ])";
153 description = "The GHC package to use.";
158 ::: {#ex-options-declarations-util-mkPackageOption-extraDescription .example}
159 ### `mkPackageOption` with additional description text
161 mkPackageOption pkgs [ "python39Packages" "pytorch" ] {
162 extraDescription = "This is an example and doesn't actually do anything.";
166 type = lib.types.package;
167 default = pkgs.python39Packages.pytorch;
168 defaultText = lib.literalExpression "pkgs.python39Packages.pytorch";
169 description = "The pytorch package to use. This is an example and doesn't actually do anything.";
174 ## Extensible Option Types {#sec-option-declarations-eot}
176 Extensible option types is a feature that allows to extend certain types
177 declaration through multiple module files. This feature only work with a
178 restricted set of types, namely `enum` and `submodules` and any composed
181 Extensible option types can be used for `enum` options that affects
182 multiple modules, or as an alternative to related `enable` options.
184 As an example, we will take the case of display managers. There is a
185 central display manager module for generic display manager options and a
186 module file per display manager backend (sddm, gdm ...).
188 There are two approaches we could take with this module structure:
190 - Configuring the display managers independently by adding an enable
191 option to every display manager module backend. (NixOS)
193 - Configuring the display managers in the central module by adding
194 an option to select which display manager backend to use.
196 Both approaches have problems.
198 Making backends independent can quickly become hard to manage. For
199 display managers, there can only be one enabled at a time, but the
200 type system cannot enforce this restriction as there is no relation
201 between each backend's `enable` option. As a result, this restriction
202 has to be done explicitly by adding assertions in each display manager
205 On the other hand, managing the display manager backends in the
206 central module will require changing the central module option every
207 time a new backend is added or removed.
209 By using extensible option types, it is possible to create a placeholder
210 option in the central module
211 ([Example: Extensible type placeholder in the service module](#ex-option-declaration-eot-service)),
212 and to extend it in each backend module
213 ([Example: Extending `services.xserver.displayManager.enable` in the `gdm` module](#ex-option-declaration-eot-backend-gdm),
214 [Example: Extending `services.xserver.displayManager.enable` in the `sddm` module](#ex-option-declaration-eot-backend-sddm)).
216 As a result, `displayManager.enable` option values can be added without
217 changing the main service module file and the type system automatically
218 enforces that there can only be a single display manager enabled.
220 ::: {#ex-option-declaration-eot-service .example}
221 ### Extensible type placeholder in the service module
224 services.xserver.displayManager.enable = mkOption {
225 description = "Display manager to use";
226 type = with types; nullOr (enum [ ]);
232 ::: {#ex-option-declaration-eot-backend-gdm .example}
233 ### Extending `services.xserver.displayManager.enable` in the `gdm` module
236 services.xserver.displayManager.enable = mkOption {
237 type = with types; nullOr (enum [ "gdm" ]);
243 ::: {#ex-option-declaration-eot-backend-sddm .example}
244 ### Extending `services.xserver.displayManager.enable` in the `sddm` module
247 services.xserver.displayManager.enable = mkOption {
248 type = with types; nullOr (enum [ "sddm" ]);
254 The placeholder declaration is a standard `mkOption` declaration, but it
255 is important that extensible option declarations only use the `type`
258 Extensible option types work with any of the composed variants of `enum`
259 such as `with types; nullOr (enum [ "foo" "bar" ])` or `with types;
260 listOf (enum [ "foo" "bar" ])`.