1# Modularity {#sec-modularity} 2 3The NixOS configuration mechanism is modular. If your 4`configuration.nix` becomes too big, you can split it into multiple 5files. Likewise, if you have multiple NixOS configurations (e.g. for 6different computers) with some commonality, you can move the common 7configuration into a shared file. 8 9Modules have exactly the same syntax as `configuration.nix`. In fact, 10`configuration.nix` is itself a module. You can use other modules by 11including them from `configuration.nix`, e.g.: 12 13```nix 14{ config, pkgs, ... }: 15 16{ imports = [ ./vpn.nix ./kde.nix ]; 17 services.httpd.enable = true; 18 environment.systemPackages = [ pkgs.emacs ]; 19 # ... 20} 21``` 22 23Here, we include two modules from the same directory, `vpn.nix` and 24`kde.nix`. The latter might look like this: 25 26```nix 27{ config, pkgs, ... }: 28 29{ services.xserver.enable = true; 30 services.displayManager.sddm.enable = true; 31 services.xserver.desktopManager.plasma5.enable = true; 32 environment.systemPackages = [ pkgs.vim ]; 33} 34``` 35 36Note that both `configuration.nix` and `kde.nix` define the option 37[](#opt-environment.systemPackages). When multiple modules define an 38option, NixOS will try to *merge* the definitions. In the case of 39[](#opt-environment.systemPackages) the lists of packages will be 40concatenated. The value in `configuration.nix` is 41merged last, so for list-type options, it will appear at the end of the 42merged list. If you want it to appear first, you can use `mkBefore`: 43 44```nix 45{ 46 boot.kernelModules = mkBefore [ "kvm-intel" ]; 47} 48``` 49 50This causes the `kvm-intel` kernel module to be loaded before any other 51kernel modules. 52 53For other types of options, a merge may not be possible. For instance, 54if two modules define [](#opt-services.httpd.adminAddr), 55`nixos-rebuild` will give an error: 56 57```plain 58The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'. 59``` 60 61When that happens, it's possible to force one definition take precedence 62over the others: 63 64```nix 65{ 66 services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org"; 67} 68``` 69 70When using multiple modules, you may need to access configuration values 71defined in other modules. This is what the `config` function argument is 72for: it contains the complete, merged system configuration. That is, 73`config` is the result of combining the configurations returned by every 74module. (If you're wondering how it's possible that the (indirect) *result* 75of a function is passed as an *input* to that same function: that's 76because Nix is a "lazy" language --- it only computes values when 77they are needed. This works as long as no individual configuration 78value depends on itself.) 79 80For example, here is a module that adds some packages to 81[](#opt-environment.systemPackages) only if 82[](#opt-services.xserver.enable) is set to `true` somewhere else: 83 84```nix 85{ config, pkgs, ... }: 86 87{ environment.systemPackages = 88 if config.services.xserver.enable then 89 [ pkgs.firefox 90 pkgs.thunderbird 91 ] 92 else 93 [ ]; 94} 95``` 96 97With multiple modules, it may not be obvious what the final value of a 98configuration option is. The command `nixos-option` allows you to find 99out: 100 101```ShellSession 102$ nixos-option services.xserver.enable 103true 104 105$ nixos-option boot.kernelModules 106[ "tun" "ipv6" "loop" ... ] 107``` 108 109Interactive exploration of the configuration is possible using `nix 110 repl`, a read-eval-print loop for Nix expressions. A typical use: 111 112```ShellSession 113$ nix repl '<nixpkgs/nixos>' 114 115nix-repl> config.networking.hostName 116"mandark" 117 118nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts 119[ "example.org" "example.gov" ] 120``` 121 122While abstracting your configuration, you may find it useful to generate 123modules using code, instead of writing files. The example below would 124have the same effect as importing a file which sets those options. 125 126```nix 127{ config, pkgs, ... }: 128 129let netConfig = hostName: { 130 networking.hostName = hostName; 131 networking.useDHCP = false; 132}; 133 134in 135 136{ imports = [ (netConfig "nixos.localdomain") ]; } 137```