✨ 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.nixfor 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.
{ 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.readDirto 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 likepkgs.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.