Skip to content

✨ Nix Style & Best Practices ​

To maintain a high-quality, professional codebase, we follow a set of strict engineering standards when writing Nix code. These guidelines ensure that the configuration is predictable, searchable, and easy for other developers to understand.

🏷️ Naming Conventions ​

Option Names ​

Use camelCase for all custom options. Choose names that describe the capability or policy, not just the package name.

  • ✅ platform.security.hardenedKernel.enable
  • ❌ platform.enable_linux_hardened

File Naming ​

  • Use default.nix for directory entry points (the main module/profile).
  • Use kebab-case for specific module files: boot-ux.nix, local-overlay.nix.

🛠️ Logic and Structure ​

1. Explicit Over Implicit ​

We avoid complex logic that hides how the system is built. If a module depends on another, it should ideally be imported explicitly or checked via config options.

2. Use of mkIf and mkMerge ​

Always wrap your module implementation in mkIf based on an enable option. This allows the module to be safely imported without automatically activating its logic.

nix
{ config, lib, pkgs, ... }:
let
  cfg = config.platform.feature;
in {
  options.platform.feature.enable = lib.mkEnableOption "Description of feature";

  config = lib.mkIf cfg.enable {
    # implementation here
  };
}

3. Clean Imports ​

Group imports logically. Always prefer relative paths (./module.nix) over complex absolute lookups unless referring to a global profile.

🛡️ Best Practices ​

Avoid "Nix Magic" ​

  • Do not use builtins.readDir to automatically import every file in a folder. It makes the code hard to grep and breaks the "explicit is better than implicit" rule.
  • Do not use with pkgs; at the top of files. It pollutes the namespace and makes it unclear where a package is coming from. Instead, use explicit references like pkgs.git.

Unfree Packages ​

Unfree software is only permitted in the graphical workstation product. Use the provided platform options to enable unfree packages globally or per-package to maintain an audit trail.

External Flake Inputs ​

Pin every external input in flake.nix. Avoid using nix-channel or unpinned URLs. This ensures that a build today will produce the exact same result a year from now.

Platform Documentation