Home Explore Blog Models CI



nixpkgs

1st chunk of `nixos/doc/manual/development/modular-services.md`
ae3525f803efeec8c742b38a3d6cbeaf5adf3d2dbdc242f40000000100000ac5

# Modular Services {#modular-services}

Status: in development. This functionality is new in NixOS 25.11, and significant changes should be expected. We'd love to hear your feedback in <https://github.com/NixOS/nixpkgs/pull/372170>

Traditionally, NixOS services were defined using sets of options *in* modules, not *as* modules. This made them non-modular, resulting in problems with composability, reuse, and portability.

A configuration management framework is an application of `evalModules` with the `class` and `specialArgs` input attribute set to particular values.
NixOS is such a configuration management framework, and so are [Home Manager](https://github.com/nix-community/home-manager) and [`nix-darwin`](https://github.com/lnl7/nix-darwin).

The service management component of a configuration management framework is the set of module options that connects Nix expressions with the underlying service (or process) manager.
For NixOS this is the module wrapping [`systemd`](https://systemd.io/), on `nix-darwin` this is the module wrapping [`launchd`](https://en.wikipedia.org/wiki/Launchd).

A *modular service* is a [module] that defines values for a core set of options declared in the service management component of a configuration management framework, including which program to run.
Since it's a module, it can be composed with other modules via `imports` to extend its functionality.

NixOS provides two options into which such modules can be plugged:

- `system.services.<name>`
- an option for user services (TBD)

Crucially, these options have the type [`attrsOf`] [`submodule`].
The name of the service is the attribute name corresponding to `attrsOf`.
<!-- ^ This is how composition is *always* provided, instead of a difficult thing (but this is reference docs, not a changelog) -->
The `submodule` is pre-loaded with two modules:
- a generic module that is intended to be portable
- a module with systemd-specific options, whose values or defaults derive from the generic module's option values.

So note that the default value of `system.services.<name>` is not a complete service. It requires that the user provide a value, and this is typically done by importing a module. For example:

<!-- Not using typical example syntax, because reading this is *not* optional, and should it should not be folded closed. -->
```nix
{
  system.services.my-service-instance = {
    imports = [ pkgs.some-application.services.some-service-module ];
    foo.settings = {
      # ...
    };
  };
}
```

## Portability {#modular-service-portability}

It is possible to write service modules that are portable. This is done by either avoiding the `systemd` option tree, or by defining process-manager-specific definitions in an optional way:

Title: Modular Services in NixOS: A New Approach to Service Definition
Summary
This document introduces "Modular Services," a new functionality in development for NixOS 25.11, designed to address issues of composability, reuse, and portability inherent in traditional NixOS service definitions. Unlike the old method where services were defined using options *within* modules, modular services are self-contained modules that define core options for a configuration management framework's service management component (e.g., `systemd` for NixOS). This modularity allows for functionality extension via `imports`. NixOS supports these modular services through options like `system.services.<name>`, which are `attrsOf submodule`. Each submodule comes pre-loaded with a generic, portable module and a systemd-specific module that builds upon the generic one. The text provides an example of how to import a service module and notes that these services can be written to be portable by either avoiding or optionally defining process-manager-specific configurations.