qnix-modules is a reusable module library for:
NixOSHome Manager- mixed
NixOS + Home Managersetups
The new structure is based on:
- profiles for composition
- modules for reusable capabilities
- options for feature schemas
- a shared
qnix.*config tree - helper functions under
lib.qnix.*
This repository is now organized around the new profile-based system. The old category-based structure is obsolete.
profiles/nixosdescribes machine rolesprofiles/homedescribes user rolesmodules/shared/qnix-options.nixdefines always-available shared schemaoptions/defines additional feature option schemasmodules/nixosimplements reusable NixOS capabilitiesmodules/homeimplements reusable Home Manager capabilitieslib/contains compatibility and context helpers
The public configuration lives under:
qnix = { ... };Rules:
- In
NixOSmodules, useconfig.qnix - In
Home Managermodules:- use
osConfig.qnixwhen integrated into NixOS - fall back to
config.qnixin standalone HM - use
qnixLib.qnix.getQnixConfigfor this
- use
.
├── flake.nix
├── garnix.yaml
├── checks/
│ └── flake.nix
├── lib/
│ ├── README.md
│ ├── default.nix
│ ├── context.nix
│ ├── options.nix
│ ├── attrs.nix
│ └── packages.nix
├── loader/
│ ├── nixos.nix
│ └── home.nix
├── options/
│ └── nixos/
├── modules/
│ ├── nixos/
│ ├── home/
│ └── shared/
│ └── qnix-options.nix
└── profiles/
├── nixos/
└── home/
The root flake.nix is intentionally minimal:
- exports
nixosModules.qnix - exports
homeManagerModules.qnix - exports
lib
It does not carry evaluation-only inputs like home-manager or nixpkgs.
The real evaluation checks live in:
This flake contains the pinned test harness:
nixpkgshome-managerpath:..back toqnix-modules
Run locally with:
nix flake check ./checksThis repo publishes and validates flakes through GitHub Actions:
.github/workflows/checks.ymlrunsnix flake check ./checkson pull requests and pushes to the default branch.github/workflows/release-tagged.ymlon tagv*: publishes the flake to FlakeHub (consumer-facing) and creates a GitHub Release with changelog notes only
The release helper commands in the client workflow assume tags like v0.1.0.
Garnix is configured to evaluate the nested checks flake directly:
Current config:
flakeDir: checksUse the NixOS loader to activate machine profiles:
(import "${inputs.qnix-modules}/loader/nixos.nix" {
inherit lib;
profiles = [
"base"
"server"
];
})The loader always imports modules/shared/qnix-options.nix and then the
selected profiles. Profiles are still responsible for importing the
implementation modules they need.
Use the Home loader to activate user profiles:
(import "${inputs.qnix-modules}/loader/home.nix" {
lib = nixpkgs.lib;
profiles = [
"base"
"developer"
];
})Important:
- the loader always imports
modules/shared/qnix-options.nix - profiles provide the actual feature/module imports
- the Home loader should use plain
nixpkgs.lib - do not override Home Manager's
lib - pass
qnixLibseparately viaextraSpecialArgs
This repo exposes helper functions under:
lib.qnix.*See:
Main helpers include:
getQnixConfighasOptionfirstExistingOptionPathsetAttrByExistingOptionPathmkIfOptiongetAttrFromPathsOrfirstExistingPackagefirstExistingPackageOr
Full usage examples for all supported modes are in:
Covered there:
NixOS onlyHome Manager onlyNixOS + Home Manager
The intended compatibility model is:
servercan use stableclientcan use unstable- modules should adapt to moved option paths and package renames
Rules:
- use
optionswhen deciding which config path to write - use
lib.qnix.setAttrByExistingOptionPathfor option path differences - use
lib.qnix.firstExistingPackage*for package name differences
This repository is in the middle of the new-system rewrite.
That means:
- the new profile-based architecture is the source of truth
- old category-based docs and assumptions are no longer valid
- the root flake stays minimal
- the
checksflake is the evaluation harness
If something in the repo still reflects the old model, treat it as migration leftovers, not as the intended design.