adeci/guix-by-nix
{ "createdAt": "2026-07-13T19:53:15Z", "defaultBranch": "main", "description": "are we guix yet?", "fullName": "adeci/guix-by-nix", "homepage": "", "language": "Nix", "name": "guix-by-nix", "pushedAt": "2026-07-30T04:06:11Z", "stargazersCount": 5, "topics": [], "updatedAt": "2026-07-30T22:48:06Z", "url": "https://github.com/adeci/guix-by-nix"}Guix by Nix
Section titled “Guix by Nix”NixOSn’t. Nix builds it. Shepherd runs it.
Guix by Nix is an interactive x86_64 QEMU VM. Nix builds it from translated Guix package graphs. The guest boots Guix Linux-libre 6.12.62-gnu and runs GNU Shepherd 1.0.9 as PID 1.
Nix evaluates the checked-in package expressions, builds the system, creates the initrd and disk image, starts QEMU, and runs the tests. Nix is not installed in the guest.
Build path
Section titled “Build path”Guix package definitions -> guix-transfer translates the evaluated derivation graph -> GuixPkgs stores the generated Nix expressions -> Nix builds the kernel and userland -> QEMU boots Guix Linux-libre -> Guix Bash runs the initrd and activation -> GNU Shepherd starts as PID 1guix-transfer converts concrete Guix derivations from /gnu/store to /nix/store. GuixPkgs checks the generated expressions into a flake.
Guix and the Guix daemon are not needed when this project is evaluated.
Guest software
Section titled “Guest software”| Part | Implementation |
|---|---|
| Kernel | Guix Linux-libre 6.12.62-gnu and its modules |
| Initrd | Guix Bash, Coreutils, kmod, and util-linux |
| Activation | A Nix-written shell script run by Guix Bash |
| PID 1 | GNU Shepherd 1.0.9 |
| Devices | eudev |
| Network | dhcpcd, openresolv, iproute2, iputils, curl, and Mozilla CA certificates |
| Login | Shadow, Linux-PAM, sudo, and Guix Bash |
| Userland | Raw translated Guix package outputs |
The guest has no systemd, D-Bus, logind, NixOS activation, GuixPkgs wrapper trees, or firmware files. Nix adds the metadata required by its VM builder to the translated kernel output. It does not rebuild or patch the kernel.
The system path contains 42 selected Guix packages:
- Shell and language: Bash, Guile
- Core tools: Coreutils, grep, sed, gawk, findutils, diffutils, procps, which, time
- Interactive tools: htop, tmux, nano, less, ncurses
- Archives: tar, gzip, bzip2, xz, zstd, cpio, patch
- Administration: util-linux, Shadow, sudo, kbd, ACL, attr, libcap, kmod, e2fsprogs
- Networking: inetutils, iproute2, iputils, dhcpcd, openresolv, curl, nss-certs
- Services and login: Shepherd, eudev, Linux-PAM
Git, an SSH server, compilers, graphical software, the Nix CLI, the Guix CLI, and both package-manager daemons are left out.
Why .unwrapped?
Section titled “Why .unwrapped?”GuixPkgs normally wraps each command so it can source that package’s generated runtime profile. That is useful for a standalone nix shell or nix run.
This VM uses each package’s .unwrapped output for its shared system path. It takes the available .runtimeEnv profile fragments, checks them, removes duplicates, and writes one /etc/profile.
Inside the VM, wrappers would repeat profile setup for every command and replace raw Guix executables with launcher scripts.
Sudo also needs a raw ELF file for its privileged copy. A wrapper script cannot be used there. Wrapped and unwrapped packages depend on the same translated Guix derivation, so .unwrapped changes only how the guest is assembled.
Sudo and ping
Section titled “Sudo and ping”The translated sudo file in the Nix store has mode 0555. During activation it is copied to /run/privileged/bin/sudo, changed to root:root, and then given mode 4755. /run/setuid-programs/sudo is a compatibility link to the same copy.
The guest account belongs to wheel and uses its own password with sudo. Ping does not use a setuid binary; activation enables unprivileged ICMP echo sockets through net.ipv4.ping_group_range.
nix run --accept-flake-config . --option filter-syscalls falseThe default app runs the VM; nix build produces the same VM runner.
Serial login credentials:
root / guix-by-nixguest / guix-by-nixThe 42 packages listed above are available directly from the login shell.
QEMU provides outbound NAT at 10.0.2.15, gateway 10.0.2.2, and resolver 10.0.2.3. The login profile points curl at the CA certificates from Guix nss-certs. Public network access still depends on the host. No inbound ports are forwarded.
From guest, shut down or reboot with:
sudo shutdownsudo rebootBoth commands act immediately. Shepherd does not accept the systemd-style now argument.
Source layout
Section titled “Source layout”flake.nix public packages, apps, configuration, and checksnix/modules/ VM configurationsnix/activation/ accounts, /etc, and privileged programsnix/initrd/ initrd module listnix/kernel/ Linux-libre adapternix/runtime/ raw packages and the merged profilenix/audit/ closure, executable, and status reportstests/ Nix checks and Python VM driversdocs/ implementation and testing notesSee the [documentation index]!(docs/README.md) for implementation and test details.