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.xserver.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), that's easy: the lists of 40packages can simply be concatenated. 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 45boot.kernelModules = mkBefore [ "kvm-intel" ]; 46``` 47 48This causes the `kvm-intel` kernel module to be loaded before any other 49kernel modules. 50 51For other types of options, a merge may not be possible. For instance, 52if two modules define [](#opt-services.httpd.adminAddr), 53`nixos-rebuild` will give an error: 54 55```plain 56The unique option `services.httpd.adminAddr' is defined multiple times, in `/etc/nixos/httpd.nix' and `/etc/nixos/configuration.nix'. 57``` 58 59When that happens, it's possible to force one definition take precedence 60over the others: 61 62```nix 63services.httpd.adminAddr = pkgs.lib.mkForce "bob@example.org"; 64``` 65 66When using multiple modules, you may need to access configuration values 67defined in other modules. This is what the `config` function argument is 68for: it contains the complete, merged system configuration. That is, 69`config` is the result of combining the configurations returned by every 70module. (If you're wondering how it's possible that the (indirect) *result* 71of a function is passed as an *input* to that same function: that's 72because Nix is a "lazy" language --- it only computes values when 73they are needed. This works as long as no individual configuration 74value depends on itself.) 75 76For example, here is a module that adds some packages to 77[](#opt-environment.systemPackages) only if 78[](#opt-services.xserver.enable) is set to `true` somewhere else: 79 80```nix 81{ config, pkgs, ... }: 82 83{ environment.systemPackages = 84 if config.services.xserver.enable then 85 [ pkgs.firefox 86 pkgs.thunderbird 87 ] 88 else 89 [ ]; 90} 91``` 92 93With multiple modules, it may not be obvious what the final value of a 94configuration option is. The command `nixos-option` allows you to find 95out: 96 97```ShellSession 98$ nixos-option services.xserver.enable 99true 100 101$ nixos-option boot.kernelModules 102[ "tun" "ipv6" "loop" ... ] 103``` 104 105Interactive exploration of the configuration is possible using `nix 106 repl`, a read-eval-print loop for Nix expressions. A typical use: 107 108```ShellSession 109$ nix repl '<nixpkgs/nixos>' 110 111nix-repl> config.networking.hostName 112"mandark" 113 114nix-repl> map (x: x.hostName) config.services.httpd.virtualHosts 115[ "example.org" "example.gov" ] 116``` 117 118While abstracting your configuration, you may find it useful to generate 119modules using code, instead of writing files. The example below would 120have the same effect as importing a file which sets those options. 121 122```nix 123{ config, pkgs, ... }: 124 125let netConfig = hostName: { 126 networking.hostName = hostName; 127 networking.useDHCP = false; 128}; 129 130in 131 132{ imports = [ (netConfig "nixos.localdomain") ]; } 133```