libguix
Unofficial Rust client library for GNU Guix.
Wraps the guix CLI and its machine-readable REPL (guix repl -t machine) so you can drive package management, system administration, and builds from Rust without parsing human-readable output. Designed for long-running operations: every write returns an Operation with a coalesced event stream and a CancelHandle.
Module map
The module tree mirrors guix --help so navigating the library reads like navigating the CLI:
| Rust | Guix CLI |
|---|---|
Guix::package() → PackageOps |
guix package (install, remove, upgrade, search, show, generations) |
Guix::system() → SystemOps |
guix system reconfigure / guix system init |
Guix::pull() → PullOps |
guix pull (user catalog + root catalog, via pkexec or already-root) |
Guix::archive() → ArchiveOps |
guix archive --authorize |
Guix::gc() → GcOps |
guix gc |
Guix::shell() → ShellOps |
guix shell |
Guix::build() → BuildOps |
guix build |
Guix::describe() → DescribeOps |
guix describe |
Examples
Search and list:
use Guix;
async
Streaming install (REPL-backed, with structured fd-3 events):
use StreamExt;
use ProgressEvent;
let mut op = guix.package.install?;
while let Some = op.events_mut.next.await
op.await_completion.await?;
Run a command in an ad-hoc environment (guix shell):
let op = guix.shell.run?;
op.await_completion.await?;
Build a package and collect its store paths (guix build):
let paths = guix.build.run_to_paths.await?;
for p in paths
Pull the user catalog, or the root catalog under pkexec:
use SystemPullOptions;
let op = guix.pull.user?; // ~/.config/guix/current
let op = guix.pull.as_root?; // /var/guix/profiles/per-user/root
Root contexts without polkit (e.g. an OS installer)
When the caller is already root and there's no desktop session — an installer on a bare TTY — set Privilege::AlreadyRoot to spawn guix directly. No pkexec, and cancellation works because the child is yours. Build-server and scheduler flags pass through via BuildOptions:
use ;
use Path;
let op = guix.system.init?;
op.await_completion.await?;
Fold the event stream into a render-ready snapshot — stage, per-item build/download state, percent — with no UI-framework dependency:
use Summary;
use StreamExt;
let mut summary = new;
while let Some = op.events_mut.next.await
Transient substitute/network failures can be retried with an opt-in policy. Streaming retry stays caller-side (an Operation's stream is consumed once), so run_with_retry covers the headless await-to-completion case:
use ;
run_with_retry.await?;
Requirements
A working guix binary on PATH (or at /run/current-system/profile/bin/guix). Tested against modern Guix releases — see MIN_GUIX_VERSION_DATE.
Under the default Privilege::Pkexec, the privileged paths (SystemOps::reconfigure / init, PullOps::as_root, ArchiveOps::authorize) need polkit actions installed and an authentication agent running in your session — the library returns a structured PolkitFailure error if either is missing. Privilege::AlreadyRoot skips polkit entirely.
Features
| Feature | Default | What it does |
|---|---|---|
tracing |
yes | Emit tracing events from the REPL actor and command helpers. |
live-tests |
no | Enables tests that shell out to a real guix on the host. |
blocking |
no | Reserved for a future blocking wrapper API. |
Embedding in a minimal-closure consumer? Set default-features = false to drop the tracing dependency. The only async runtime requirements in your own scope are tokio and tokio-stream.
Status
Pre-1.0. The API will shift as the GUI consuming it (in the same repo) grows. Pin a specific version if you depend on it.
License
Dual-licensed under either of:
- MIT License (LICENSE-MIT)
- Apache License 2.0 (LICENSE-APACHE)
at your option. Pick whichever fits your project — the library is permissively licensed so it can be embedded in tools under any licence, including the GPL-licensed guix-gui frontend in this same repository.