# nixos-raspberrypi turns a Raspberry Pi into a declarative NixOS target

> The nixos-raspberrypi flake supplies the bootloader infrastructure, vendor kernel packages with matched firmware, board modules and a binary cache, so a Pi can be installed in one step with nixos-anywhere. The new kernel boot method supports multiple NixOS generations, and the optimised overlays come with a rebuild cost.

**nvmd/nixos-raspberrypi** — Nix flake for a fully declarative NixOS on Raspberry Pi

- Repository: https://github.com/nvmd/nixos-raspberrypi
- Stars: 669 · Forks: 74
- Language: Nix
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/nvmd-nixos-raspberrypi

## One flake for firmware, kernel and board specific packages

nixos-raspberrypi describes itself as an unopinionated Nix flake for infrastructure, vendor packages, kernel and some optimised third party packages for NixOS running on Raspberry Pi devices. The word unopinionated does real work in that sentence, because the alternative style of Pi support is a set of hard coded assumptions in a single configuration. Here the pieces are separate and selectable. There is a bootloader infrastructure layer that manages the Raspberry Pi firmware partition, whose path is configurable through the firmware path option and which is where most hand rolled Pi installs go wrong. There is a vendor kernel package layer that pairs the right kernel with the right firmware. And there is an overlay layer for vendor and optimised packages, with libcamera and ffmpeg given as examples. The payoff is the first line of the README, that you can deploy NixOS fully declaratively in one step with a tool like nixos-anywhere, with the caveat noted in the same sentence that kexec is unfortunately not supported.

## Three boot methods, and the old one is on its way out

The bootloader handling is the part of this project that has changed most recently, and the README is clear about the direction of travel. The legacy method is kernelboot, which remains the default for the Pi 5, and uboot is the default bootloader for all the other boards. The third is kernel, described as a new generation of kernelboot that supports multiple NixOS generations, which is the default for the Pi 5 sd image and installer images and is recommended for new installations. The multi generation support is the substantive change, because it means a Pi can keep more than one system closure available and roll back to the previous one, which is the property most people want from a declarative system and which the older methods did not give them. The partitioning itself is integrated with the bootloader activation scripts and happens on a NixOS generation switch, which is what lets nixos-anywhere complete without any interactive intervention. The configuration options live under the raspberry-pi bootloader setting, and the Raspberry config.txt file is configurable through a separate option set with a module file that translates the Raspberry defaults into Nix format.

## Kernel and firmware are published as a matched set

The vendor package layer exists to solve a problem that is easy to underestimate. A Pi needs a kernel, the Raspberry firmware, the device trees and overlays, and the wireless firmware, and a mismatch between them is a source of hardware that is not detected, a camera that does not work or a boot that fails after a kernel update. The default vendor package set contains a matching triple, expressed in the README as a kernel package per board model together with the Raspberry firmware including device trees and overlays, and the wireless firmware. The latest stable version compatible with the board is selected in the flake module by default, so you are not expected to pin that yourself. For a fleet of identical Pis this is the difference between one kernel decision and a hundred, and for a single Pi it is the difference between remembering to update three things in step and not having to think about it.

## Three helper functions replace nixosSystem

Instead of calling nixpkgs.lib.nixosSystem, the flake offers helpers intended as a drop in replacement. The plain one is the same as the upstream function. The second applies the Raspberry Pi optimised overlays globally, which the README warns may lead to more rebuilds. The third is the installer variant, the same as the global overlay version but with additional installer specific modules. They all take two optional arguments, the nixpkgs to use, which defaults to the nixpkgs of this flake, and whether to trust the binary caches of the project, which defaults to true. A configuration looks like this.

```nix
nixosConfigurations.rpi5-demo = nixos-raspberrypi.lib.nixosSystem {
  specialArgs = inputs;
  modules = [
    {
      # Hardware specific configuration, see section below for a more complete
      # list of modules
      imports = with nixos-raspberrypi.nixosModules; [
        raspberry-pi-5.base
        raspberry-pi-5.display-vc4
        raspberry-pi-5.bluetooth
      ];
    }
    ({ config, pkgs, lib, ... }: {
      networking.hostName = "rpi5-demo";
```

The system tags are then derived from the board variant, the bootloader and the kernel version, which is how the flake keeps track of what a given machine actually is. If you would rather assemble the configuration yourself, the README points at the internal implementation and at using the regular nixpkgs function, with one requirement: you must pass the flake into specialArgs so the board modules can find it.

## Board modules, display connectors and a 16k page size option

The module list is organised by board, with base modules for the Zero 2 W, the Pi 3, the Pi 4 and the Pi 5, plus a USB gadget ethernet module that configures ethernet emulation over USB for any board. The display options differ by generation, and the README makes the Pi 4 and Pi 5 difference explicit. On a Pi 4 the display vc4 module is the only display configuration option. On a Pi 5 there are two, one for a regular display connected and one for an RP1 connected display covering the DPI, composite and MIPI DSI connectors, and you pick one depending on the primary GPU configuration. The Pi 5 also has a page size option, described as an optional memory optimisation that uses 16k pages instead of the default 64k for jemalloc, saving memory and reducing fragmentation, and which may fix problems caused by a memory page size discrepancy. The same entry warns that it may cause lots of rebuilds and that it applies only to systems running the default Pi 5 kernel with 16k memory pages. That is a good example of the trade this project keeps making: real memory savings on a 8GB board, paid for in build time.

## A binary cache, and the price of the global overlay

The flake publishes its own binary cache through cachix, and using it is a small configuration change in the flake file.

```nix
nixConfig = {
  extra-substituters = [
    "https://nixos-raspberrypi.cachix.org"
  ];
  extra-trusted-public-keys = [
    "nixos-raspberrypi.cachix.org-1:4iMO9LXa8BqhU+Rpg6LQKiGa2lsNh/j2oiYLNOQ5sPI="
  ];
};
```

The module list shows what that cache buys, with an import for injecting the overlays that carry the kernel, the firmware and the vendor packages, another for trusting the binary cache with prebuilt packages for the currently locked nixpkgs, and optional imports for putting the Raspberry Pi packages in the global package set and for injecting the optimised overlays globally, which provides ffmpeg at several major versions, kodi, libcamera and vlc among others. The README is candid about the consequence of that last one, noting that it may cause lots of rebuilds even though many of the packages should be available from the binary cache. The devshells directory holds a nix build to cachix script listing what is published, which is a useful artefact if you want to know what you can expect to download rather than compile.

## Install images for four boards, and a note on the project status

The flake provides installation SD card images for the Raspberry Pi Zero 2, the Pi 3, the Pi 4 and the Pi 5, based on the nixos-images project from the nix community, and the README points at a separate demo repository with a worked example. The installer helper function is the way to build those images, and the same configuration you will run on the device is the one you build the image from, which is the point of the exercise. The project structure in the tree reflects the same separation, with a flake file and lock file at the top, a lib directory for the helper functions, a modules directory holding the configuration modules including the bootloader one, an overlays directory for the optimised packages, a pkgs directory for the vendor packages, and devshells for development. Releases are dated rather than semantic, with 1.20260801.0 published in August 2026 and earlier ones in July and May, and the default branch is develop while the README recommends following the main branch of the repository as the stable one. The licence is MIT.

## Conclusion

nixos-raspberrypi suits a team that wants Raspberry Pi hosts to be reproducible and rebuildable like any other NixOS machine, since the flake ties the kernel, the firmware and the board modules together and removes the manual firmware partition handling that usually blocks a declarative install. It is the wrong choice if you want a Raspberry Pi that boots a normal Raspberry Pi OS image, or if you cannot accept a kernel and firmware pairing chosen by the project rather than by you, since the vendor packages are selected for you by the flake module. Verify three things before you build on it: which boot method your board uses, because the kernelboot method is legacy, uboot is the default for boards other than the Pi 5, and the new kernel method is the default for Pi 5 sd images, whether the global overlay injection is worth the rebuild cost it will trigger in your build, and that the device tree overlay for your display matches the connector, since the Pi 5 splits the regular and RP1 attached display configurations. The licence is MIT, the default branch is develop, and the last push was on 2026-10-19.

## FAQ

### What does the nixos-raspberrypi flake provide?

It provides bootloader infrastructure that manages the firmware partition, vendor kernel packages with matched Raspberry firmware, device trees and wireless firmware, board specific configuration modules, and overlays holding optimised third party packages such as libcamera and ffmpeg.

### Which bootloader should I use on a Raspberry Pi 5?

The kernelboot method is legacy, uboot is the default for boards other than the Pi 5, and the new kernel method, a newer generation of kernelboot that supports multiple NixOS generations, is the default for the Pi 5 sd image and installer images and is recommended for new installations.

### How do I install NixOS on a Pi with this flake?

The README says the flake lets you deploy NixOS fully declaratively in one step with tools like nixos-anywhere, with the caveat that kexec is not supported. Partition provisioning is integrated with the bootloader activation scripts on a generation switch, so no interactive intervention is needed during the install.

### Is there a binary cache for the Raspberry Pi packages?

Yes, the project publishes one through cachix, and you add it as an extra substituter with the matching trusted public key in your flake configuration. The README notes that the global overlay import may still cause many rebuilds even though many packages are available from the cache.

## Sources

- [Issues](https://github.com/nvmd/nixos-raspberrypi/issues)
- [License: MIT](https://github.com/nvmd/nixos-raspberrypi/blob/develop/LICENSE)
- [nvmd/nixos-raspberrypi on GitHub](https://github.com/nvmd/nixos-raspberrypi)
- [README](https://github.com/nvmd/nixos-raspberrypi/blob/develop/README.md)
- [Releases](https://github.com/nvmd/nixos-raspberrypi/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nvmd-nixos-raspberrypi
