Denix: A Library for Creating Scalable NixOS and Home Manager Configurations with Modules, Hosts, and Rices

Denix: A Library for Creating Scalable NixOS and Home Manager Configurations with Modules, Hosts, and Rices

GitHub: GitHub - yunfachi/denix: Nix library for creating scalable NixOS and Home Manager configurations with modules, hosts, and rices
Documentation (English, Russian): Denix Documentation
My configuration: GitHub - yunfachi/nix-config: My NixOS and Home Manager flake for all my hosts, including servers, laptops and desktops, built with Denix

What is Denix?

Denix is a Nix library designed to create scalable configurations for NixOS and Home Manager. It provides functions that transform input data into a module following a specific algorithm. Thanks to this approach, if you ever need to create a module without using Denix, you can simply import the file, and everything will work seamlessly.

Documentation

This post mainly consists of excerpts from the documentation available at Denix Documentation. This is my first attempt at writing documentation, so I would appreciate any feedback on mistakes or areas for improvement. The documentation is available in both English and Russian. You can also check out my real configuration built entirely with Denix: GitHub - yunfachi/nix-config: My NixOS and Home Manager flake for all my hosts, including servers, laptops and desktops, built with Denix.

Why and Who Needs Denix?

Denix is primarily useful for simplifying the creation, editing, and readability of configuration code. It eliminates the need to manually write common expressions for your own modules, hosts, rices, etc.

If you plan to scale your configuration across multiple machines (hosts), want to manage various system settings (rices) that can be easily changed with a single command, and prefer to write readable and clean code (Introduction to Denix Options), then Denix is worth considering. On the other hand, if you are building a small configuration for a single machine and don’t intend to expand it, Denix might not be necessary.

Configuration templates using Denix can be found in the templates directory of the GitHub repository: github:yunfachi/denix?path=templates.

Examples of Modules, Hosts, and Rices

I don’t want to make this post too long, as you can find detailed explanations in the Denix documentation. Below are a few examples of how Denix can be used.

Example of custom NixOS module code without Denix
{lib, config, ...}: {
  options = {
    example = {
      enable = lib.mkEnableOption "example" // {default = true;};
      hostnames = lib.mkOption {
        type = lib.types.listOf lib.types.str;
        default = [];
      };
    };
  };

  config = lib.mkIf (!config.example.enable) {
    networking.hosts."127.0.0.1" = config.example.hostnames;
  };
}
The same functionality using Denix
{delib, ...}: delib.module {
  name = "example";

  options.example = with delib; {
    enable = enableOption true;
    hostnames = listOfOption str [];
  };

  nixos.ifEnabled = {cfg, ...}: {
    networking.hosts."127.0.0.1" = cfg.hostnames;
  };
}

Example of a host configuration module using Denix
{delib, ...}: delib.host {
  name = "macbook";

  rice = "dark";
  type = "desktop";

  homeManagerSystem = "x86_64-darwin";
  home.home.stateVersion = "24.05";

  shared.myconfig = {
    services.openssh.authorizedKeys = ["ssh-ed25519 ..."];
  };
}

Example of a rice configuration module using Denix
{delib, ...}: delib.rice {
  name = "dark";

  home.stylix = {
    polarity = "dark";
    colors = {
      # ...
    };
  };
}

Yes, Denix may not be for everyone, and it might not seem useful if you haven’t encountered the types of issues it aims to solve.

9 Likes