From NixOS Wiki
Revision as of 21:54, 9 June 2019 by Mth (talk | contribs)
Jump to: navigation, search

Modules are files combined by NixOS to produce the full system configuration. A module contains a Nix expression. It declares options for other modules to define (give a value). It processes them and defines options declared in other modules.[1]

For example, /etc/nixos/configuration.nix is a module. Most other modules are in Nixpkgs-link.pngnixos/modules.


Modules have the following syntax:

  imports = [
    # paths to other modules

  options = {
    # option declarations

  config = {
    # option definitions

There is a shorthand for modules without any declarations:

  require = [
    # paths to other modules

  # option definitions


A module can be turned into a function accepting an attribute set.

{ config, pkgs, ... }:
  # ...

It may require the attribute set to contain:

The configuration of the entire system.
All option declarations refined with all definition and declaration references.
The attribute set extracted from the Nix package collection and enhanced with the nixpkgs.config option.
The location of the module directory of NixOS.


Imports are paths to other NixOS modules that should be included in the evaluation of the system configuration. A default set of modules is defined in Nixpkgs-link.pngnixos/modules/module-list.nix. These don't need to be added in the import list.


Declarations specify a module's external interfaces.

optionName = mkOption {
  # ...

They are created with mkOption, a function accepting a set with following attributes:[2][3]


The type of the option. It may be omitted, but that’s not advisable since it may lead to errors that are hard to diagnose.


The default value used if no value is defined by any module. A default is not required; but if a default is not given, then users of the module will have to define the value of the option, otherwise an error will be thrown.


An example value that will be shown in the NixOS manual.


A textual description of the option, in DocBook format, that will be included in the NixOS manual.


Modules were introduced to allow extending NixOS without modifying its source code.[4] They also allow splitting up configuration.nix, making the system configuration easier to maintain and to reuse.


put into hello.nix in the same folder as your configuration.nix.

{ lib, pkgs, config, ... }:
with lib;                      
  cfg =;
in { = {
    enable = mkEnableOption "hello service";
    greeter = mkOption {
      type = types.string;
      default = "world";

  config = lib.mkIf cfg.enable { = {
      wantedBy = [ "" ];
      serviceConfig.ExecStart = "${pkgs.hello}/bin/hello -g'Hello, ${escapeShellArg cfg.greeter}!'";

Add the following to your configuration.nix

  imports = [ ./hello.nix ];
  services.hello = {
    enable = true;
    greeter = "Bob";

Advanced Use Cases

Compatibility Issues with Different Nixpkgs Versions

Module options between Nixpkgs revisions can sometimes change in incompatible ways.

For example, the option services.nginx.virtualHosts.*.port in nixpkgs-17.03 was replaced by services.nginx.virtualHosts.*.listen in nixpkgs-17.09. If configuration.nix has to accommodate both variants, options can be inspected:

{ options, ... }: {
  services.nginx.virtualHosts.somehost = { /* common configuration */ }
    // (if builtins.hasAttr "port" (builtins.head
          then { port = 8000; }
          else { listen = [ { addr = ""; port = 8000; } ]; });

Abstract imports

To import a module that's stored somewhere (but for which you have neither an absolute nor a relative path), you can use NIX_PATH elements or specialArgs from nixos/lib/eval-config.nix.

This is useful for e.g. pulling modules from a git repository without adding it as a channel, or if you just prefer using paths relative to a root you can change (as opposed to the current file, which could move in the future).

  inherit (import <nixpkgs> {}) writeShellScriptBin fetchgit;
  yourModules = fetchgit { ... };
in rec {
  nixos = import <nixpkgs/nixos/lib/eval-config.nix> {
    modules = [ ./configuration.nix ];
    specialArgs.mod = name: "${yourModules}/${name}";

  /* use nixos here, e.g. for deployment or building an image */
{ config, lib, pkgs, mod, ... }: {
  imports = [
    (mod "foo.nix")


More complex usages

The examples below contain:

  • a child `mkOption` inherits their default from a parent `mkOption`
  • reading default values from neighbouring `mkOption`(s) for conditional defaults
  • passing in the config, to read the hostName from a submodule (email system)
  • setting default values from attrset (email system)
  • generating documentation for custom modules (outside of nixpkgs). See here


(sorry, dont' have more time to make this into a nice little guide yet, but this links should be pretty good introductions into more advanced module system usages) qknight


  1. NixOS Manual, Chapter 42. Writing NixOS Modules
  2. Nixpkgs-link.pnglib/options.nix#L21-L54
  3. NixOS Manual, 42.1. Option Declarations
  4. [Nix-dev] NixOS: New scheme

See also