Files
Nix-Vibe/.github/skills/nix-module/SKILL.md
T

3.5 KiB

name, description, argument-hint
name description argument-hint
nix-module Create or update a NixOS or Home Manager module following Nix-Vibe conventions. Use when adding a new service, desktop app, hardware support, or shared configuration module. Use when the user asks to add a package, service, or application module. <module-name> [service|desktop|hardware|core]

Nix Module Creation

When to Use

  • Adding a new service (e.g., a new containerized app, daemon, or web service)
  • Adding a new desktop application module
  • Adding hardware support (e.g., new device driver, firmware)
  • Creating a new shared core module
  • The user asks to "add support for X" or "create a module for X"

Module Pattern

All service/feature modules MUST follow this pattern:

{ config, pkgs, lib, ... }:

{
  options.services.<name> = {
    enable = lib.mkEnableOption "description of the service";
    # Additional options as needed
  };

  config = lib.mkIf config.services.<name>.enable {
    # Configuration here
  };
}

Reference implementation: modules/services/immich.nix

Procedure

1. Determine Module Type

Type Directory Example
Service (daemon, container, webapp) modules/services/ immich, jellyfin, ntfy
Desktop app modules/desktop/apps/ soundux, opencode, freeshow
Desktop environment modules/desktop/ gnome.nix, gui.nix
Hardware support modules/hardware/ fingerprint.nix
Core system config modules/core/ common.nix, settings.nix, fonts.nix

2. Create the Module File

Service Module Template

{ config, pkgs, lib, ... }:

{
  options.services.<service-name> = {
    enable = lib.mkEnableOption "<Service Description>";
    port = lib.mkOption {
      type = lib.types.port;
      default = <default-port>;
      description = "Port for <service>";
    };
    # Add data directories, user config, etc. as needed
  };

  config = lib.mkIf config.services.<service-name>.enable {
    # Service-specific configuration
    
    # For stateful services, ensure data directories exist
    systemd.tmpfiles.rules = [
      "d /var/lib/<service> 0700 <user> <group> -"
    ];
    
    # Open firewall if needed
    networking.firewall.allowedTCPPorts = [ config.services.<service-name>.port ];
  };
}

Desktop App Module Template

{ pkgs, ... }:

{
  environment.systemPackages = with pkgs; [
    <package-name>
  ];
}

3. Register in Host Configuration

Import the module in the target host's configuration.nix:

imports = [
  # ...existing imports...
  ../../modules/services/<module-name>.nix
];

Then enable it:

services.<service-name>.enable = true;

4. Update README.md

Add the new software to the Software Inventory table with the appropriate host columns.

5. Validate

Run the full validation workflow. See nix-flake-rebuild.

Key Conventions

Secrets

Never hardcode secrets. Use SOPS:

sops.secrets."<host>/<secret-name>" = {
  owner = "<user>";
  group = "users";
  mode = "0440";
};

See docs/sops-secrets.md for details.

Overlay Awareness

  • If a package needs NVIDIA/CUDA or NDI, it should only be added to x1carbon (the only host using the full overlays set)
  • Desktops/laptops use desktopOverlays (stable without CUDA); servers use serverOverlays

Module Composition

  • Core modules (modules/core/common.nix) apply to ALL hosts
  • Desktop modules only apply to GUI hosts
  • Service modules are imported per-host as needed