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) andsrc/diff.rs/src/show.rs(diff and display). - The tree model is built in
src/tree/data.rs(functions likebuild_config_tree,get_children_at_path,sort_branches_first). - Rendering helpers are in
src/tree/render.rsandsrc/tree/widgets.rs, while colour handling lives insrc/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.
runbuilds aConfigTreeby callingconvert(fromsrc/json2nix.rs) which parses the tracking JSON.convertis the most‑called internal routine (9 call sites).- The tree is then passed to
build_diff_lines→find_hunks, which walk the tree withget_children_at_path(6 call sites) andformat_value_full(6 call sites) to create a diff buffer. - Rendering is performed in
render_frame(insrc/tui.rs), which repeatedly callsfooter_pill(23 calls) andrender_dep_list(6 calls). Those functions ultimately invoke colour helpers (node_icon,node_name_color,value_color) defined insrc/tree/icons.rs. - Input handling is isolated in
src/tree/input.rs(handle_input→rect_contains24 times,jump_to_path9 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/workflowsor other CI configuration. → Add a GitHub Actions workflow that runscargo build --releaseand the test suite on push and PR. - Medium – No Dependabot – Only
Cargo.toml/Cargo.lockpresent, no update bot. → Commit.github/dependabot.ymlfor 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.rseach 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.