This repository has been archived on 2026-08-30. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
dotfiles/docs/nix.md

3.5 KiB

Nix Conventions

This document records local Nix style and design conventions. Use these conventions when changing this flake. Read this document with docs/dictionary.md.

Names

Reserve lib for nixpkgs.lib

Use lib only for the base nixpkgs.lib value. Do not use lib for project functions. Use dotfiles.lib for library functions passed through module arguments. Use dotfiles.<name> for assembly functions passed through module arguments.

Avoid:

{
  lib = dotfilesFunctions;
}

Use:

{
  lib = nixpkgs.lib;
  dotfiles.lib = dotfilesFunctions;
}

Name project function namespaces by role

Put pure project functions under dotfiles.lib. Put functions that create modules, systems, or assembly values under dotfiles. This keeps data-only functions separate from functions that carry flake context.

Avoid:

dotfiles.lib.mkHost { hostName = "neogaia"; }

Use:

dotfiles.mkHost { hostName = "neogaia"; }

File Placement

Put files in the directory that owns their role

Choose the file location before writing a Nix file. Put assembly files under flake/. Do not add library files until this repository has a library directory. Put modules under modules/. Put host configurations under hosts/<name>/. Put host-side guest wiring under guests/. Put registry definitions under registry/. Keep flake.nix focused on inputs and output wiring. Do not add root-level Nix files other than flake.nix.

A module is self-contained configuration under modules/. A module configures one program, service, or subsystem. Files under hosts/, guests/, and modules/ return NixOS modules.

Function Arguments

Use closed interfaces for assembly files and library files

Use exact function argument patterns for assembly files and library files. The caller owns the argument set for these files. The imported file names each accepted attribute. The imported file rejects stale or accidental extra attributes.

Avoid:

{
  inputs,
  lib,
  self,
  ...
}:

Use:

{
  inputs,
  lib,
  self,
}:

Pass function arguments explicitly

Pass only the values an assembly file or library file needs. Bind lib to the base nixpkgs.lib value at the call site. Use inherit only for values that keep the same name.

Avoid:

import ./flake inputs

Use:

let
  inherit (nixpkgs) lib;
in
import ./flake { inherit lib inputs self; }

Keep NixOS module interfaces open

Files under hosts/, guests/, and modules/ return NixOS modules. nixosSystem owns their argument shape. Name each argument the module uses. Keep ... so the module accepts standard arguments and special arguments.

Avoid:

{
  config,
  lib,
  pkgs,
  registry,
}:

Use:

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

let Bindings

Use role-specific binding names

A let binding name must explain the value's role in the expression. Avoid names that describe only the value's type.

Avoid:

let
  names = lib.attrNames hosts;
in
lib.genAttrs names mkHost

Use:

let
  hostNames = lib.attrNames hosts;
in
lib.genAttrs hostNames mkHost

Standard Library Calls

Qualify standard library calls in flake assembly

Use qualified standard library calls inside assembly files. Use lib.mapAttrs instead of inheriting mapAttrs from lib. This keeps the source of each function visible.

Avoid:

let
  inherit (lib) mapAttrs;
in
mapAttrs f attrs

Use:

lib.mapAttrs f attrs