manic-systems/nixos-core

Core NixOS utilities in safe, portable Rust for NixOS and friends

Rust

96

206 commits

updated Sep 19, 2026

See the code

README

nixos-core

nixos-core is a multi-call binary implementing core NixOS system utilities in safe, portable Rust, replacing some of the Perl, Bash and Python scripts that are generally load-bearing for safety and performance. While some of those scripts _can_ be replaced through various means (such as the Perlless and Bashless profiles in Nixpkgs) the available methods usually change how your system behaves, and may yield general instability or even breakage as is the case with the /etc overlay system.

Synopsis

This repository provides a multi-call 1 Rust binary that aims to replace some of the fragile and occasionally undesirable Bash, Perl and Python scripts as well as some utilities that were already written in Rust in a fast, portable and easy-to-audit codebase. See the motivation section for why we also try to replace Rust code with more Rust code, or why this repository exists in the first place.

The NixOS module and the nixos-core crate replaces legacy Bash and Perl scripts that execute on every NixOS system during boot and activation. While the amount of Bash and Perl has been steadily decreasing in Nixpkgs, non-Systemd spins of NixOS don't always get the same luxury. Thus, nixos-core aims to be the one-size-fits-all that you can use on both NixOS and spins of NixOS requiring a solution to those common problems.

The multi-call design of nixos-core, like BusyBox, reduces binary size and simplifies deployment so that it can fit on your NixOS or NixOS-like system. The project is intentionally modular to fit the particular needs of any user through the NixOS module and feature flags.

Compatibility Matrix/Overview

The scope of this program is currently limited to what Nixpkgs permits in terms of replacing the legacy solutions cleanly through the module system. Here is a general overview of what can currently be replaced:

CommandOriginal ComponentPurposeStatus
update-users-groupsupdate-users-groups.plManage /etc/passwd, /etc/group, /etc/shadowFirst-class
setup-etcsetup-etc.plAtomically update /etc/staticFirst-class
init-script-builderinit-script-builder.shCreate generic /sbin/initFirst-class
stage-1-initstage-1-init.shInitrd bootstrapFirst-class
stage-2-initstage-2-init.shSystem activationFirst-class
persistImpermanenceProject persistent paths into an ephemeral rootFirst-class

While the project is rather new, base rewrites are complete and mostly verified through VM tests and even in real systems. If you're interested in testing nixos-core on your system, but are skeptical, you may be interested in enabling it gradually through the NixOS module knobs and test each individual component. As it stands, nixos-core does not change anything that can "brick" your system, i.e., you can easily roll back a generation in case something goes wrong.

Usage

The nixos-core crate provides a multi-call binary invocable either as a symlink:

# Invoke the update-users-groups command
$ update-users-groups /nix/store/...-users-groups.json

Or explicitly as a subcommand:

# Subcommand of update-users-groups
$ nixos-core update-users-groups /nix/store/...-users-groups.json

This usage pattern, like the mono-repo design, is a deliberate choice that allows reusing code and shared patterns without the cognitive overhead of cross-referencing separate projects. It also lets us provide a relatively small binary that does everything.

Feature Flags/Overrides

All commands provided by the nixos-core binary are enabled by default, but also feature-gated through Rust's feature flags. This design lets you disable commands that you don't want or need at build time and choose which binaries to install, and what components to replace. Feature flags work both with cargo (--features) and as package arguments when building with Nix:

[(prev: final: {
  nixos-core = prev.nixos-core.override {
    withStage1 = false; # e.g., skip initrd bootstrap
  }
})];

Additional feature flags, also exposed as overridable package attributes, control the behavior of stage 2. These are bootspec, systemd-integration, and full-nixos-init-compat, providing complete compatibility with the pre-existing behavior of Nixpkgs' stage 2. If you are developing a systemd-less NixOS variant but still want to manage stage 2, you can disable systemd-integration while retaining bootspec support. Most of these features are described in detail in the stage2 crate's README.

Motivation

nixos-core aims to be a safe, independent core utility for NixOS and NixOS derivatives that build their own tooling from scratch, such as MicrOS and Finix. The main goals of this project is being a fast, portable and consistent utilities written in clean Rust, from one coherent codebase, and designed modular enough through feature flags and NixOS module knobs to fit into any system and derivative project. It is an out-of-tree module to meet those goals without the behavioral changes imposed by Nixpkgs alternatives like Userborn, the /etc overlay, or nixos-init. That is not to say those are fundamentally incompatible with this project, but they are different. There may be room for collaboration in the future.

Contributing

We're always open to new contributions. Please keep in mind that as a critical system utility, nixos-core has strict contribution requirements. We expect you to write safe, principled Rust and test your code accordingly through unit and integration tests. If you have a good idea, but can't exactly be sure how to proceed you may open an issue to discuss your changes with us beforehand.

Hacking

nixos-core is built with the latest stable Rust available in Nixpkgs, which is 1.94.0 at the time of writing. The Minimum Supported Rust Version (MSRV) is therefore set at 1.94.0, and may change as the language evolves.

Safety

  • No unsafe code except for unavoidable syscalls (crypt, geteuid)
  • Explicit error handling with the ? operator
  • Dry-run mode available for all destructive operations

Testing

This repository provides a few VM test to verify correct behaviour. Those are rather limited at the time but should provide some amount of guidance for you.

# Run all VM tests that are exposed under `checks`
$ nix flake check

# Run a specific VM tests
$ nix build .#checks.x86_64-linux.boot

You can find the available NixOS VM tests in the nix/vm-tests directory. If you're adding new features, you should add a new test component or some subtests that verify that your code works exactly as expected. There is also this neat little command you can use to get a list of checks supported by each system:

# Get a list of checks supported by each system. For now all systems
# support the same group of checks, but it might differ in the future.
$ nix eval .#checks --apply 'x: builtins.mapAttrs (_: builtins.attrNames) x' --json

Pipe it into jq for a nicer result.

License

This project is derived from Nixpkgs, originally licensed under the MIT License. Original copyright and MIT license text are preserved in licenses/MIT.txt located in the repository root. This project and all project code/documentation are distributed under the Mozilla Public License (MPL) version 2.0. See LICENSE for more details on the exact conditions. An online copy is provided here.

Footnotes

  1. Multicall in Unix refers to a type of binary that allows multiple commands to be executed through a single executable, depending on the name used to invoke it. See here for a more comprehensive explanation. Historically multicall binaries have also been called "BusyBox-like", which should probably be what you're thinking of when you hear "multi-call" for the purposes of this project.

init
nixos
rust

Contributors

NotAShelf

135 commits

amaanq

62 commits

faukah

3 commits

manic-systems/nixos-core

Core NixOS utilities in safe, portable Rust for NixOS and friends

Rust

96

206 commits

updated Sep 19, 2026

See the code

README

nixos-core

nixos-core is a multi-call binary implementing core NixOS system utilities in safe, portable Rust, replacing some of the Perl, Bash and Python scripts that are generally load-bearing for safety and performance. While some of those scripts _can_ be replaced through various means (such as the Perlless and Bashless profiles in Nixpkgs) the available methods usually change how your system behaves, and may yield general instability or even breakage as is the case with the /etc overlay system.

Synopsis

This repository provides a multi-call 1 Rust binary that aims to replace some of the fragile and occasionally undesirable Bash, Perl and Python scripts as well as some utilities that were already written in Rust in a fast, portable and easy-to-audit codebase. See the motivation section for why we also try to replace Rust code with more Rust code, or why this repository exists in the first place.

The NixOS module and the nixos-core crate replaces legacy Bash and Perl scripts that execute on every NixOS system during boot and activation. While the amount of Bash and Perl has been steadily decreasing in Nixpkgs, non-Systemd spins of NixOS don't always get the same luxury. Thus, nixos-core aims to be the one-size-fits-all that you can use on both NixOS and spins of NixOS requiring a solution to those common problems.

The multi-call design of nixos-core, like BusyBox, reduces binary size and simplifies deployment so that it can fit on your NixOS or NixOS-like system. The project is intentionally modular to fit the particular needs of any user through the NixOS module and feature flags.

Compatibility Matrix/Overview

The scope of this program is currently limited to what Nixpkgs permits in terms of replacing the legacy solutions cleanly through the module system. Here is a general overview of what can currently be replaced:

CommandOriginal ComponentPurposeStatus
update-users-groupsupdate-users-groups.plManage /etc/passwd, /etc/group, /etc/shadowFirst-class
setup-etcsetup-etc.plAtomically update /etc/staticFirst-class
init-script-builderinit-script-builder.shCreate generic /sbin/initFirst-class
stage-1-initstage-1-init.shInitrd bootstrapFirst-class
stage-2-initstage-2-init.shSystem activationFirst-class
persistImpermanenceProject persistent paths into an ephemeral rootFirst-class

While the project is rather new, base rewrites are complete and mostly verified through VM tests and even in real systems. If you're interested in testing nixos-core on your system, but are skeptical, you may be interested in enabling it gradually through the NixOS module knobs and test each individual component. As it stands, nixos-core does not change anything that can "brick" your system, i.e., you can easily roll back a generation in case something goes wrong.

Usage

The nixos-core crate provides a multi-call binary invocable either as a symlink:

# Invoke the update-users-groups command
$ update-users-groups /nix/store/...-users-groups.json

Or explicitly as a subcommand:

# Subcommand of update-users-groups
$ nixos-core update-users-groups /nix/store/...-users-groups.json

This usage pattern, like the mono-repo design, is a deliberate choice that allows reusing code and shared patterns without the cognitive overhead of cross-referencing separate projects. It also lets us provide a relatively small binary that does everything.

Feature Flags/Overrides

All commands provided by the nixos-core binary are enabled by default, but also feature-gated through Rust's feature flags. This design lets you disable commands that you don't want or need at build time and choose which binaries to install, and what components to replace. Feature flags work both with cargo (--features) and as package arguments when building with Nix:

[(prev: final: {
  nixos-core = prev.nixos-core.override {
    withStage1 = false; # e.g., skip initrd bootstrap
  }
})];

Additional feature flags, also exposed as overridable package attributes, control the behavior of stage 2. These are bootspec, systemd-integration, and full-nixos-init-compat, providing complete compatibility with the pre-existing behavior of Nixpkgs' stage 2. If you are developing a systemd-less NixOS variant but still want to manage stage 2, you can disable systemd-integration while retaining bootspec support. Most of these features are described in detail in the stage2 crate's README.

Motivation

nixos-core aims to be a safe, independent core utility for NixOS and NixOS derivatives that build their own tooling from scratch, such as MicrOS and Finix. The main goals of this project is being a fast, portable and consistent utilities written in clean Rust, from one coherent codebase, and designed modular enough through feature flags and NixOS module knobs to fit into any system and derivative project. It is an out-of-tree module to meet those goals without the behavioral changes imposed by Nixpkgs alternatives like Userborn, the /etc overlay, or nixos-init. That is not to say those are fundamentally incompatible with this project, but they are different. There may be room for collaboration in the future.

Contributing

We're always open to new contributions. Please keep in mind that as a critical system utility, nixos-core has strict contribution requirements. We expect you to write safe, principled Rust and test your code accordingly through unit and integration tests. If you have a good idea, but can't exactly be sure how to proceed you may open an issue to discuss your changes with us beforehand.

Hacking

nixos-core is built with the latest stable Rust available in Nixpkgs, which is 1.94.0 at the time of writing. The Minimum Supported Rust Version (MSRV) is therefore set at 1.94.0, and may change as the language evolves.

Safety

  • No unsafe code except for unavoidable syscalls (crypt, geteuid)
  • Explicit error handling with the ? operator
  • Dry-run mode available for all destructive operations

Testing

This repository provides a few VM test to verify correct behaviour. Those are rather limited at the time but should provide some amount of guidance for you.

# Run all VM tests that are exposed under `checks`
$ nix flake check

# Run a specific VM tests
$ nix build .#checks.x86_64-linux.boot

You can find the available NixOS VM tests in the nix/vm-tests directory. If you're adding new features, you should add a new test component or some subtests that verify that your code works exactly as expected. There is also this neat little command you can use to get a list of checks supported by each system:

# Get a list of checks supported by each system. For now all systems
# support the same group of checks, but it might differ in the future.
$ nix eval .#checks --apply 'x: builtins.mapAttrs (_: builtins.attrNames) x' --json

Pipe it into jq for a nicer result.

License

This project is derived from Nixpkgs, originally licensed under the MIT License. Original copyright and MIT license text are preserved in licenses/MIT.txt located in the repository root. This project and all project code/documentation are distributed under the Mozilla Public License (MPL) version 2.0. See LICENSE for more details on the exact conditions. An online copy is provided here.

Footnotes

  1. Multicall in Unix refers to a type of binary that allows multiple commands to be executed through a single executable, depending on the name used to invoke it. See here for a more comprehensive explanation. Historically multicall binaries have also been called "BusyBox-like", which should probably be what you're thinking of when you hear "multi-call" for the purposes of this project.

init
nixos
rust

Contributors

NotAShelf

135 commits

amaanq

62 commits

faukah

3 commits

Languages

Rust

70.4%

Nix

29.6%