The Problem

Operators need to understand why a NixOS option has a particular value and how two configurations differ. The standard nixos-rebuild diff works at the derivation level, hiding the option‑level provenance that can be critical for debugging complex module sets.

What This Does

nixos-config-tui is a terminal UI that reads the JSON tracking files emitted by a patched Nix evaluator and lets users browse the configuration tree, inspect individual option values, and diff two configurations option‑by‑option.

  • The core logic lives in src/main.rs (CLI parsing) and src/diff.rs / src/show.rs (diff and display).
  • The tree model is built in src/tree/data.rs (functions like build_config_tree, get_children_at_path, sort_branches_first).
  • Rendering helpers are in src/tree/render.rs and src/tree/widgets.rs, while colour handling lives in src/tree/icons.rs.

All UI interaction is driven by the tui module (src/tui.rs) which sets up the crossterm/ratatui event loop.

How It Is Wired

Execution starts at main in src/main.rs (line 124). The CLI dispatches to either run (src/diff.rs:17) for the diff command or run_show (src/show.rs) for the show command.

  • run builds a ConfigTree by calling convert (from src/json2nix.rs) which parses the tracking JSON. convert is the most‑called internal routine (9 call sites).
  • The tree is then passed to build_diff_lines → find_hunks, which walk the tree with get_children_at_path (6 call sites) and format_value_full (6 call sites) to create a diff buffer.
  • Rendering is performed in render_frame (in src/tui.rs), which repeatedly calls footer_pill (23 calls) and render_dep_list (6 calls). Those functions ultimately invoke colour helpers (node_icon, node_name_color, value_color) defined in src/tree/icons.rs.
  • Input handling is isolated in src/tree/input.rs (handle_input → rect_contains 24 times, jump_to_path 9 times).

The most central file by call volume is src/tree/data.rs (27 functions, referenced from five other files). It owns the data model and the bulk of the algorithmic work, making it a high‑impact change point. No circular imports were detected, but the depth of nesting (up to 10 levels) in diff.rs, show.rs, and tree/input.rs makes the control flow hard to follow.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/nixos-config-tui
cd nixos-config-tui

# Build the binary (requires Rust toolchain)
cargo build --release

# Example workflow (as documented in README)
# 1. Enter a shell with the patched Nix evaluator
nix shell github:oddlama/nix/thunk-origins-v1 \
          github:oddlama/nixpkgs/thunk-origins-v1#nixos-config

# 2. Build a tracked configuration
nix build --print-out-paths .#nixosConfigurations.host1.config.system.build.toplevel

# 3. Show a configuration
./target/release/nixos-config show /nix/store/...-nixos-toplevel-tracked

# 4. Diff two configurations
./target/release/nixos-config diff /nix/store/OLD /nix/store/NEW

The binary name (nixos-config) is produced by Cargo; the README’s usage examples assume it is installed in the user’s PATH.

Real‑World Use

A CI pipeline that builds NixOS images for multiple hosts can invoke nixos-config diff $OLD $NEW after each build to generate a concise option‑level changelog. The output can be posted to Slack or attached to a merge‑request, giving developers immediate insight into why a system behaved differently without digging into the full derivation diff.

Code Health & Issues

  • High – No test suite – 15 source files, no test files. → Add unit tests for each public entry point and a CI step to run them.
  • High – No CI workflow – No .github/workflows or other CI configuration. → Add a GitHub Actions workflow that runs cargo build --release and the test suite on push and PR.
  • Medium – No Dependabot – Only Cargo.toml/Cargo.lock present, no update bot. → Commit .github/dependabot.yml for the Rust ecosystem.
  • High – Cognitive load – Deep nesting (max indentation depth 10) in src/diff.rs, src/show.rs, src/tree/input.rs. → Refactor with early returns and extract helper functions.
  • High – Duplicated code – Repeated 6‑line blocks across src/diff.rs, src/show.rs, src/tree/render.rs, src/tree/input.rs. → Create shared utilities to obey DRY.
  • Medium – Oversized files – src/tree/data.rs, src/tree/input.rs, src/tree/render.rs each exceed 600 lines. → Split by responsibility (e.g., separate traversal, rendering, and data definitions).

No Dockerfile, secret leakage, or missing license was detected; the repository includes both Apache‑2.0 and MIT notices.

The Bottom Line

nixos-config-tui provides a practical, option‑level view of NixOS configurations, useful for debugging and change‑tracking. The code works but suffers from deep nesting, duplicated logic, and large monolithic files, which increase maintenance risk. Adding tests, CI, and modest refactoring would make it reliable for production environments. It is best suited for teams already comfortable with Rust and Nix who need fine‑grained insight into configuration differences.