Personal Monorepo ❄️
README.md

rust-nixos#

NixOS with a Rust user space.

Overview#

rust-nixos is a NixOS configuration that systematically replaces core C user space components with Rust alternatives using NixOS's system.replaceDependencies.replacements mechanism. The result is a bootable NixOS system where the init system, shell, privilege escalation, and core utilities are all written in Rust.

This serves as both a proof-of-concept for an oxidized Linux distribution and as an integration test bed for Rust system components — particularly rust-systemd, which replaces PID 1 and the entire systemd suite.

Replacements#

Component C Original Rust Replacement Module Status
Init / service manager systemd rust-systemd systemd.nix ✅ Active
Privilege escalation sudo sudo-rs sudo.nix ✅ Active
Shell bash brush bash.nix 🚧 Experimental
Core utilities coreutils uutils coreutils.nix 🚧 Experimental

Modules marked Active are enabled in the default rust-nixos configuration. Experimental modules are available but commented out in default.nix pending further integration work.

How It Works#

NixOS's system.replaceDependencies.replacements performs a closure-wide substitution — every package in the system closure that depends on the original package gets rebuilt (or binary-patched) to reference the replacement instead. This means the swap is not just surface-level; the entire dependency graph is rewritten.

For example, systemd.nix sets systemd.package = pkgs.rust-systemd-systemd, which is a wrapper package that starts from the real systemd store path (to get unit files, udev rules, tmpfiles configs, etc.) and overlays the Rust binaries on top. The result is a package that is layout-compatible with systemd but runs Rust code.

The bash.nix module is more involved — it builds a small C wrapper that translates bash's CLI conventions (single-character flags like -eu) into brush's option syntax, handles signal setup for serial consoles, and execvs into brush.

Configurations#

Configuration Description
nixos-nix Vanilla NixOS baseline (no Rust replacements)
rust-nixos NixOS with Rust user space (active replacements enabled)

Both configurations share base.nix, which sets up a QEMU guest with systemd-networkd, systemd-resolved, and an auto-login user.

Usage#

Prerequisites#

  • Nix with flakes enabled
  • just (available in the dev shell)
  • cloud-hypervisor for VM execution
  • A TAP network device (vmtap0) for VM networking, or sudo access for automatic setup

Build & Run#

# Build the disk image
just build

# Boot the VM interactively (serial console)
just run

Testing#

# Run automated boot test (checks for login prompt, detects panics)
just test

# Boot test with custom timeout
just test-timeout 60

# Boot test with log file
just test-log boot.log

# Quick pass/fail (no streaming output)
just test-quiet

# Boot test then keep VM running for debugging
just test-keep

The test-boot.sh script launches the VM in cloud-hypervisor, captures serial output, and checks for success patterns (login prompt) and failure patterns (kernel panic, Rust panics, emergency mode). It handles network setup automatically in CI environments.

Analysis#

# Compare closure sizes between vanilla and oxidized NixOS
just compare-closure

# Diff package lists between the two configurations
just compare-packages

# Explore the dependency tree
just tree

Project Structure#

rust-nixos/
├── default.nix      # Nix entry point: dev shell + NixOS configurations
├── base.nix         # Shared NixOS config (QEMU guest, networkd, resolved, users)
├── systemd.nix      # systemd → rust-systemd replacement
├── sudo.nix         # sudo → sudo-rs replacement
├── bash.nix         # bash → brush replacement (experimental)
├── coreutils.nix    # coreutils → uutils replacement (experimental)
├── justfile         # Build, run, and test commands
└── test-boot.sh     # Automated VM boot test script
  • rust-systemd — The Rust systemd replacement that powers this configuration
  • rust-pkg-config — A Rust pkg-config implementation used in the build toolchain