Skip to content

nix-maid

Systemd-native dotfile management

nix-maid โ„๏ธ๐Ÿงน

Systemd + Nix dotfile management.


Nix-Maid allows you to configure your dotfiles and systemd services at the user level, similar to Home-Manager.

Nix-Maid is more lightweight and stays closer to the native Nix, systemd and tmpfiles abstractions.

Features and Design Choices โ€‹

  • ๐Ÿชถ Lightweight: Pushing the execution to other tools, making the project almost a pure-nix library.
  • ๐ŸŒ Portable: Defers the value of your home directory, so the same configuration works for different users.
  • ๐Ÿšซ No Legacy: API redesigned from scratch, avoiding past mistakes like mkOutOfStoreSymlink.
  • โšก Fast: Uses a static directory, enabling rollbacks without traversing your entire home or diffing profiles.

Documentation โ€‹

You can find the API documentation here: https://viperml.github.io/nix-maid/api

Example and cool features โ€‹

Installation for standalone, NixOS module and Flakes in the Installation section of the manual.

The following is an example of a nix-maid configuration. Nix-maid doesn't have its own CLI to install, but rather is installed with Nix itself:

nix
# my-config.nix
let
  sources = import ./npins;
  pkgs = import sources.nixpkgs;
  nix-maid = import sources.nix-maid;
in
nix-maid pkgs {
  # Add packages to install
  packages = [
    pkgs.yazi
    pkgs.bat
    pkgs.eza
  ];

  # Create files in your home directory
  file.home.".gitconfig".text = ''
    [user]
      name=Maid
  '';

  file.xdg_config."zellij/config.kdl".source = ./config.kdl;

  # `file` supports a mustache syntax, for dynamically resolving the value of {{home}}
  # This same configuration is portable between systems with different home dirs
  file.xdg_config."hypr/hyprland.conf".source = "{{home}}/dotfiles/hyprland.conf";

  # Define systemd-user services, like you would on NixOS
  systemd.services.waybar = {
    path = [ pkgs.waybar ];
    script = ''
      exec waybar
    '';
    wantedBy = [ "graphical-session.target" ];
  };

  # Configure gnome with dconf or gsettings
  gsettings.settings = {
    "org.gnome.mutter"."experimental-features" = [
      "scale-monitor-framebuffer" "xwayland-native-scaling"
    ];
  };

  dconf.settings = {
    "/org/gnome/desktop/interface/color-scheme" = "prefer-dark";
  };

  # Mustache syntax is also available in dynamicRules
  systemd.tmpfiles.dynamicRules = [
    "L {{xdg_config_dir}}/hypr/workspaces.conf - - - - {{home}}/dotfiles/workspaces.conf"
  ];
}
$ nix-env -if ./my-config.nix
$ activate

Status โ€‹

I use nix-maid daily, and I invite you to do so. Currently, only base modules are provided (linking files, defining systemd services), but you are invited to add high-level modules in a PR (e.g. programs.git).

Attribution โ€‹

  • Using sd-switch, originally extracted from Home-Manager, to load new systemd units.
  • Hjem and Hjem-Rum do a similar approach with systemd-tmpfiles.