Library / SDK
gytis-ivaskevicius/flake-utils-plus avatar
gytis-ivaskevicius/flake-utils-plus

flake-utils-plus: NixOS flakes with the configuration split into channels and hosts

Use Nix flakes without any fluff.

546 stars56 forksNixMIT

At a glance

What is it?
flake-utils-plus is a library for generating NixOS flake configurations, extending numtide's flake-utils with a channel concept, per-host defaults and a set of exporters. Its author is explicit that the goal is to keep the fluff down, and the config surface is documented in full in the README.
Who is it for?
Adopt flake-utils-plus if you already write NixOS flakes and want channels, per-host defaults and overlays handled by a library rather than by hand-written glue in every flake. Do not adopt it if you want a full framework, since the author positions it explicitly as simpler than frameworks such as DevOS, and a single-host configuration does not need it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 75 days ago.
What is it written in?
Mainly Nix, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A library over flake-utils, not a framework

Flake-utils-plus exposes a library abstraction to painlessly generate NixOS flake configurations, and the design goal is stated twice: the biggest design goal is to keep down the fluff, and the library is meant to be easy to understand and use, aiming to be far simpler than frameworks such as DevOS, previously called nixflk.

That positioning explains the whole design. It extends flake-utils by numtide, and everything exported by fu can be used from this flake, so it is a superset rather than a replacement. The unit of work is the lib.mkFlake function, described as a clean and pleasant to use flakes abstraction, and the attributes you can see from flake.nix are a small set of channels, hosts and outputs.

The channel concept is the main addition. A channel is a nixpkgs reference, and the library lets you have several of them at once, with configuration shared between them, with patches applied to selected ones, and with overlays applied to selected ones. The README lists the attributes: channelsConfig for configuration applied to all nixpkgs references, hostDefaults for default configuration shared between host definitions, outputsBuilder as a clean way to export packages and apps, and sharedOverlays for overlays applied on all imported channels.

The licence is MIT, the primary language is Nix, the default branch is master, and the last push was on 2026-08-10. The release history is v1.6.0 from 2026-05-23, v1.5.1 from 2024-07-02 and 1.5.0 from 2024-06-18, so the current major is almost two years ahead of the previous one and the project moves slowly.

The branching policy changed, and it changes how you should consume it

The first section of the README is about branching policy, and it is the kind of note that saves a broken build.

From now on master serves as a development branch, where previously staging was used for such purposes, and you are asked to use tags for stable releases of flake-utils-plus. The reasoning that follows is that with the improvements in the test harness, releases might happen more frequently, and sticking to a tagged release might offer better trade-offs going forward.

So the repository is a library that is consumed as a flake input, and the input is a tag. The difference matters because a flake input can follow a branch, and following master means tracking a development branch of a library you are using to build a machine. The tag is the stable artefact.

The rest of the project infrastructure is visible in the top level listing. There is a flake.nix and flake.lock, a lib/ directory holding the library itself, an examples/ directory with four worked configurations, a devShell.nix, a tests/ directory, and a .github/ directory. The presence of a tests directory and the mention of a test harness in the branching note are consistent, since the tests are what makes the releases more frequent.

There is also a Discord server linked at the top, and the README says to create an issue or ping the author there if you need help, which is a small thing but a reasonable signal about how a one-person library handles support.

The configuration surface, as documented in the README

The documentation section gives the full option list with examples, and the shape of it is the easiest way to understand what the library does.

The entry point is mkFlake, and the self and inputs arguments are required:

nix
  # `self` and `inputs` arguments are REQUIRED!
  inherit self inputs;

  # Supported systems, used for packages, apps, devShell and multiple other definitions. Defaults to `flake-utils.lib.defaultSystems`.
  supportedSystems = [ "x86_64-linux" ];

Then there are the channel attributes. channelsConfig is configuration shared between all channels, sharedOverlays holds overlays applied to all channels, channels.<name>.input is the nixpkgs flake reference to use, autogenerated from inputs by default. Each channel then has its own config with options like allowUnfree, its own patches list, and its own overlaysBuilder, which is a function of channels.

The host side has hostDefaults, which sets the default architecture, the default modules passed to all hosts, the default channel name, and extra arguments merged with each host's own. Each host then sets its system, its channelName, its extraArgs, its specialArgs, its modules, its output and its builder, with defaults for most of them.

The outputsBuilder is the last piece and it is where the flake outputs come from. It is a function of channels, and the README shows it producing apps, packages, a defaultApp, a defaultPackage and a devShell, with a mkApp helper that takes a derivation and an executable path.

So the whole abstraction is: inputs become channels, channels plus hostDefaults become hosts, and hosts plus the outputsBuilder become the flake outputs. That is a small amount of vocabulary, and the README's full listing of it is the documentation.

Exporters, and the REPL for poking at the result

Beyond the flake itself, the library ships a set of exporters, and each one exists to solve a specific duplication problem.

lib.exportModules takes a list of paths and generates a module attribute that looks like this: { a = import ./a.nix; b = import ./b.nix; }. It is a convenience for the common case where several files are meant to be attributes of one module.

lib.exportOverlays takes channels and exports all overlays from them as an appropriately namespaced attribute set, and the point is that users can instantiate it with their nixpkgs version. lib.exportPackages is similar but outputs them as packages for the platforms defined in meta.platforms, and the README notes the difference: unlike overlays, these packages are consistent across flakes, which allows them to be cached.

That caching point is the one to pay attention to. Overlays are a build input that differs per flake, so nothing about them can be shared. A package built from an overlay, though, is a concrete derivation, and if the derivation is the same the binary cache will serve it. Exporting packages rather than overlays is what turns per-flake configuration into shared build output.

Then there is the repl. The pkgs.fup-repl attribute is a package that adds a kick-ass repl, and it has two forms: running it bare loads your system repl into scope along with pkgs and lib from the nixpkgs input, and giving it a path to a flake.nix loads that flake instead.

The examples directory is where these are used in anger, with a minimal-multichannel example, an exporters example, a home-manager+nur+neovim example, and a darwin example. The README recommends referring to people's examples when setting up your own, and links the author's own dotfiles as the reference implementation, along with a GitHub code search for other flakes using it.

Editorial conclusion

Adopt flake-utils-plus if you already write NixOS flakes and want channels, per-host defaults and overlays handled by a library rather than by hand-written glue in every flake. Do not adopt it if you want a full framework, since the author positions it explicitly as simpler than frameworks such as DevOS, and a single-host configuration does not need it. Before you start, read the branching policy note, because master now serves as the development branch and the tags are the stable releases, and pick a tagged release rather than tracking master.

Frequently asked questions

What is flake-utils-plus and how does it relate to flake-utils?

It is a library for generating NixOS flake configurations that extends numtide's flake-utils, so everything exported by flake-utils can be used from it. The added abstraction is lib.mkFlake, along with channels, host defaults and a set of exporters, and the author positions it as simpler than frameworks such as DevOS.

Should I use the master branch or a tag of flake-utils-plus?

The README says master now serves as a development branch, where staging was previously used, and asks you to use tags for stable releases. It suggests sticking to a tagged release for better trade-offs, since releases may happen more frequently with the improved test harness.

What do the exporters in flake-utils-plus do?

lib.exportModules generates a module attribute from a list of paths, lib.exportOverlays exports all overlays from channels as a namespaced attribute set, and lib.exportPackages is the similar function for packages across the platforms in meta.platforms. The README notes that unlike overlays, these packages are consistent across flakes, which allows them to be cached.

What is the fup-repl package in flake-utils-plus?

It is a package that adds a repl. Running it bare loads your system repl into scope along with pkgs and lib from the nixpkgs input, and passing it the path to a flake.nix loads that flake instead.

Official sources

  1. gytis-ivaskevicius/flake-utils-plus on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/gytis-ivaskevicius-flake-utils-plus.svg)](https://hysenlabs.com/projects/gytis-ivaskevicius-flake-utils-plus)

Was this useful?