NixOS Module Integration with OpenLogi: Declarative Logitech Device Management

OpenLogi ships a native NixOS module that declaratively installs the daemon, udev rules, and user-level systemd service through the programs.openlogi option set defined in packaging/linux/nixos-module.nix.

The AprilNEA/OpenLogi repository provides first-class NixOS support through a dedicated module that eliminates manual configuration. This integration allows you to manage Logitech devices declaratively using standard NixOS configuration syntax. Understanding the NixOS module integration with OpenLogi enables system administrators to deploy the background agent consistently across machines while leveraging the project's Rust-based toolchain.

How the OpenLogi NixOS Module Works

Enabling the Module via programs.openlogi

The module exposes its interface through the programs.openlogi attribute set, declared at lines 12–22 of packaging/linux/nixos-module.nix. This option set provides three key configuration knobs:

  • enable: Toggles the entire integration on or off
  • package: Allows overriding the default OpenLogi derivation
  • launchAtLogin: Controls whether the agent starts automatically with graphical sessions
options.programs.openlogi = {
  enable = lib.mkEnableOption "OpenLogi, a local-first Logitech device manager";
  package = lib.mkPackageOption pkgs "openlogi" { };
  launchAtLogin = lib.mkOption {
    type = lib.types.bool;
    default = true;
    description = "Whether to start the OpenLogi agent with graphical sessions.";
  };
};

Source: nixos-module.nix lines 12–22

System-Wide Integration

When programs.openlogi.enable evaluates to true, the module performs two critical system-level modifications at lines 24–27. It appends the OpenLogi package to environment.systemPackages, making the openlogi-agent binary available in the global $PATH. Simultaneously, it registers the package's udev rules through services.udev.packages, ensuring the kernel recognizes Logitech hardware connections immediately.

config = lib.mkIf cfg.enable {
  environment.systemPackages = [ cfg.package ];
  services.udev.packages = [ cfg.package ];

Source: nixos-module.nix lines 24–27

User-Level systemd Service

The module creates a per-user systemd service named openlogi-agent at lines 28–39. The service configuration uses lib.getExe' cfg.package "openlogi-agent" to locate the binary path dynamically. When launchAtLogin is enabled, the service attaches to graphical-session.target, ensuring the agent starts only after the user session initializes.

systemd.user.services.openlogi-agent = {
  description = "OpenLogi background agent";
  wantedBy = lib.optionals cfg.launchAtLogin [ "graphical-session.target" ];
  after = [ "graphical-session.target" ];
  partOf = lib.optionals cfg.launchAtLogin [ "graphical-session.target" ];
  serviceConfig = {
    ExecStart = lib.getExe' cfg.package "openlogi-agent";
    Restart = "on-failure";
    RestartSec = 5;
  };
};

Source: nixos-module.nix lines 28–39

Flake Outputs and Wiring

The flake.nix file exposes the module through the nixosModules.openlogi output at lines 99–108. This wiring imports packaging/linux/nixos-module.nix and passes the default package as an argument. The flake also sets up the build environment at lines 31–38 using oxalica/rust-overlay to provide a recent Rust toolchain, ensuring the openlogi package compiles correctly against NixOS system libraries.

Configuring OpenLogi on NixOS

To activate the integration, import the flake's module output into your configuration.nix and enable the feature:

{ pkgs, ... }:

{
  imports = [
    # Reference the OpenLogi module from your flake input

    inputs.openlogi.nixosModules.openlogi
  ];

  programs.openlogi = {
    enable = true;              # Activates the module

    launchAtLogin = true;       # Auto-starts with graphical sessions

    # package = pkgs.openlogi;  # Optional: custom derivation override

  };
}

Apply the configuration with:

sudo nixos-rebuild switch

If you disable launchAtLogin, start the agent manually using:

systemctl --user start openlogi-agent.service

Module Architecture and Source Files

File Purpose
flake.nix Defines flake outputs including nixosModules.openlogi, configures the Rust toolchain via oxalica/rust-overlay, and builds the package using packaging/linux/package.nix.
packaging/linux/nixos-module.nix Implements the programs.openlogi interface, manages system package installation, udev rule registration, and the user-level systemd service definition.
packaging/linux/package.nix Contains the Nix derivation that compiles OpenLogi from source using the Rust toolchain provided by the flake.

Summary

  • OpenLogi provides a native NixOS module located at packaging/linux/nixos-module.nix that integrates the daemon, udev rules, and user services declaratively.
  • The programs.openlogi option set controls enablement, package selection, and autostart behavior through standard NixOS configuration.
  • System integration automatically adds the binary to environment.systemPackages and registers device rules via services.udev.packages.
  • User-level service management creates a systemd unit that conditionally binds to graphical-session.target based on the launchAtLogin setting.
  • Flake compatibility ensures reproducible builds by managing the Rust toolchain and exposing the module through nixosModules.openlogi.

Frequently Asked Questions

How do I import the OpenLogi NixOS module into my configuration?

Add the OpenLogi flake as an input to your system flake, then import inputs.openlogi.nixosModules.openlogi into your configuration.nix imports list. This exposes the programs.openlogi options namespace automatically.

Can I override the OpenLogi package version in the NixOS module?

Yes. Set programs.openlogi.package to a custom derivation. The module uses lib.mkPackageOption with a default pointing to the flake-built package, but any package containing the openlogi-agent binary and udev rules will function correctly.

How do I prevent OpenLogi from starting automatically at login?

Set programs.openlogi.launchAtLogin = false; in your configuration. This removes the graphical-session.target dependency from the systemd service, requiring you to start the agent manually with systemctl --user start openlogi-agent.service.

Where are the udev rules installed when using the OpenLogi module?

The module appends the OpenLogi package to services.udev.packages, which merges the rules into the system-wide udev configuration. The rules are extracted from the out directory of the specified package derivation during the NixOS build process.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →