Public NixOS + Home Manager flake.
This repo contains the public, shareable part of the setup. flake.nix uses
public-host-definitions.nix and lib/mk-flake-outputs.nix to export:
- NixOS system outputs:
desktop,laptop,wsl - Home Manager outputs:
miko@desktop,miko@laptop,miko@wsl - Helper attrs:
hostDefinitions,homeDefinitions,formatter.x86_64-linux,homeModules,nixosModules,lib
There are two main ways to use this flake:
nixosConfigurations.<host>is a full NixOS machine configuration.homeConfigurations."<user@host>"is a Home Manager user configuration.
If you want to use the repo exactly as it is checked in today, those output names are the ones to use. If you want to adopt it for yourself, those are also the names and paths you will usually change first.
See what the flake exports:
nix flake showApply a full NixOS host configuration:
sudo nixos-rebuild switch --flake .#desktopApply only the Home Manager configuration:
home-manager switch --flake .#miko@desktopIf home-manager is not already in PATH, use:
nix run nixpkgs#home-manager -- switch --flake .#miko@desktopIf you want to validate an output without switching to it, build it directly:
nix build .#nixosConfigurations.desktop.config.system.build.toplevel --no-link
nix build '.#homeConfigurations."miko@desktop".activationPackage' --no-linkFormat Nix files:
nix fmtReplace desktop and miko@desktop with any other output name shown by
nix flake show.
The main directories are:
lib/mk-flake-outputs.nix- the generic flake output builder used by this repo and companion repos.public-host-definitions.nix- the public host inventory, including the default host-linked Home Manager users.hosts/default.nix- shared NixOS settings imported into every host.hosts/desktop/,hosts/laptop/,hosts/wsl/- host-specific NixOS modules.profiles/workstation/- reusable system profile imported by bothdesktopandlaptop.modules/users/- shared system user modules reused by host-specific user wiring.modules/wsl/- reusable WSL system module for the publicwslhost and companion flakes.home/common/- shared Home Manager modules split into CLI-first and GUI-oriented layers.home/miko/- personal Home Manager base plus workstation-specific overlays for the main user.home/miko/mango/scripts/- packaged helper scripts used by the Mango session modules.home/wsl/- WSL-specific Home Manager overlay for themiko@wsloutput.themes/- Stylix theme files and assets.examples/private-repo/- example companion flake layered on top of this public repo.
Some relationships are worth knowing up front:
desktopandlaptopboth importprofiles/workstation/, which now includes the shared Stylix policy for workstation hosts.desktopandlaptopboth usehome/miko/as their personal base home module throughpublic-host-definitions.nix.- The host-specific user modules in
hosts/desktop/user.nix,hosts/laptop/user.nix, andhosts/wsl/user.nixall build on the shared base user module inmodules/users/miko.nix. home/default.nixnow imports the shared CLI layer, while workstation homes opt into the shared GUI layer throughhome/miko/workstation.nix.- Shared graphical Home Manager settings for desktop and laptop live in
home/miko/workstation.nix. - The desktop-only and laptop-only Home Manager settings live in
home/miko/desktop.nixandhome/miko/laptop.nixand are attached throughpublic-host-definitions.nix. wsluseshosts/wsl/andhome/wsl/, which overlays WSL-specific settings on top ofhome/miko/base.nixand the shared CLI layer.
Use these rules of thumb when deciding where to put changes:
- Shared NixOS settings for every host go in
hosts/default.nix. - Reusable system modules shared by some hosts go in
profiles/. - Host-specific system settings go in
hosts/<host>/. - Shared Home Manager settings go in
home/common/. - User-specific Home Manager base settings go in the matching user tree such as
home/miko/. - Host- or environment-specific Home Manager overlays can live under paths like
home/wsl/.
If you want to add or rename a public host output, edit
public-host-definitions.nix.
If you want to add or rename a public Home Manager output that belongs to a
host, edit public-host-definitions.nix.
The public host definitions in public-host-definitions.nix are the main
source of truth for exported public machines. Each host definition there can
set:
hostPathfor the NixOS module pathhomefor the default Home Manager user linked to that hosthomeModulesfor extra Home Manager modules appended to that linked homesystemModulesfor extra NixOS modulessystemfor the target platformwsl = truefor WSL hosts
When a host defines home = { username; path; ...; }, the builder derives a
matching homeDefinitions entry and homeConfigurations."<user>@<host>"
output automatically.
Explicit home definitions are still supported for standalone Home Manager outputs that do not belong to a host. Those entries can set:
usernamefor the Home Manager usernamepathfor the Home Manager module pathhomeDirectoryto override the default/home/<username>when neededsystemfor the target platformhomeModulesfor extra Home Manager modules
In the current public repo, both nixosConfigurations and the default public
homeConfigurations come from the host inventory, so extending a host is also
the normal way to extend its user home.
The merge behavior in lib/mk-flake-outputs.nix is worth knowing because it is
not a plain recursive attrset merge:
hostPathis picked field-by-field, so an extra definition replaces the base value when it sets one.systembehaves the same way ashostPath: extra wins if set, otherwise the base value is kept.homeis merged field-by-field forusername,path, andhomeDirectory; extra values override only the fields they set.wslis OR-ed, so once either side setswsl = true, the merged host remains WSL-enabled.systemModulesare appended as(base.systemModules or [ ]) ++ (extra.systemModules or [ ]).homeModulesare appended as(base.homeModules or [ ]) ++ (extra.homeModules or [ ]).
mkFlakeOutputs can also accept optional explicit home inventories through
baseHomeDefinitions and extraHomeDefinitions. Those are best reserved for
standalone Home Manager outputs. When either of those sets is non-empty,
homeDefinitions and homeConfigurations come from the explicit home
definitions instead of the host-derived fallback. Explicit home definition
entries use Home Manager-shaped fields:
usernamepathhomeDirectorysystemhomeModules
If an explicit home definition name follows the public "<user>@<host>"
pattern and the matching host exists, the builder also wires that home back
into nixosConfigurations.<host> so the host can still embed its Home Manager
user configuration.
Stylix is intentionally split by responsibility:
themes/one-dark.nixowns the shared palette, wallpaper, fonts, cursor, icons, and opacity defaults.profiles/workstation/stylix.nixowns workstation system-side theme policy and disables Stylix's automatic Home Manager import.home/miko/stylix.nixowns Home Manager-side target selection and manual program overrides such as Waybar, Mako, Hyprlock, Foot, and Zathura.public-host-definitions.nixonly wires the relevant Stylix modules into the exported public outputs.
If you are changing the theme source, start in themes/one-dark.nix. If you are
changing which Home Manager targets Stylix should manage, start in
home/miko/stylix.nix. If you are changing workstation-wide system-side Stylix
behavior, start in profiles/workstation/stylix.nix.
The shared Zsh setup is also split by responsibility:
lib/shared-zsh-config.nixis the shared source of aliases and interactive shell helpers.home/common/zsh.nixis the Home Manager entry point and adds Home Manager-specific integrations such asprograms.fzf.enableZshIntegration,programs.zoxide.enableZshIntegration, and thelfshell helper.modules/shared-zsh.nixis the NixOS wrapper for hosts that want the shared interactive Zsh setup without Home Manager.
If a host already uses Home Manager, prefer home/common/zsh.nix through the
normal home module tree. Use nixosModules.sharedZsh only for hosts that need a
system-level fallback without Home Manager.
The reusable WSL system module in modules/wsl/system.nix defines the
baseline interop policy used by the public wsl host and exported for
companion flakes:
- explicit WSL interop and automount defaults
wsl.confdefaults for automount, interop, and generated networking filesnixConfig.wsl.automount.uidandnixConfig.wsl.automount.gidoptions for overriding the default automount ownership policy
The reusable WSL Home Manager module in modules/wsl/home.nix defines the
hybrid user-space policy used by the public miko@wsl home and exported for
companion flakes:
- optional Windows-backed wrappers for
ssh,scp,ssh-add, andgpg - optional use of the Windows OpenSSH agent pipe through
SSH_AUTH_SOCK - a WSL-aware
wsl-opencommand for links and non-text files - optional MIME defaults that send browser, PDF, image, and media opening to Windows
The ownership split is:
public-host-definitions.nixmarks the publicwslhost withwsl = true, which makes the flake builder add the upstreamnixos-wslmodule.modules/wsl/system.nixowns the public repo's WSL policy and setswsl.enable = lib.mkDefault trueso hosts importing it normally do not need to repeat that toggle.modules/wsl/home.nixowns the reusable WSL Home Manager policy and is exported ashomeModules.wsl.hosts/wsl/default.niximports the public WSL module plus local host/user wiring, but no longer repeatswsl.enable.
Companion flakes can reuse it through nix-config.nixosModules.wsl.
Companion flakes can reuse the Home Manager side through nix-config.homeModules.wsl.
Companion flakes can also reuse nix-config.nixosModules.sharedZsh for hosts
that want the shared interactive Zsh setup without Home Manager.
The public home/wsl/ module now just selects the default hybrid policy for
miko@wsl by importing modules/wsl/home.nix and enabling:
- Windows-backed SSH and GPG helpers
- the Windows SSH agent pipe
- Windows-first opening for browser links, PDFs, images, and media
That keeps WSL hybrid by default while leaving each behavior easy to disable or override in companion flakes.
Typical WSL commands:
sudo nixos-rebuild switch --flake .#wsl
home-manager switch --flake .#miko@wslHybrid expectations for the public wsl home:
- terminal, shell, git, Neovim, and other dev tooling stay Linux-native
- browser links, PDFs, images, and media open through Windows by default
- Linux GUI defaults remain attached to workstation homes instead of every home
This public repo is set up to be used on its own, but it also includes an
example of the private-companion pattern in examples/private-repo/.
The idea is:
- keep shareable config in this public repo
- keep private overlays in a separate flake
- make the private flake import this one and extend host definitions as overlays
The example companion flake does that by taking nix-config as an input and
calling the same output builder with extra host definitions:
{
inputs.nix-config.url = "git+ssh://git@example.com/you/nix-config.git";
outputs =
{ nix-config, ... }:
let
nixosModules = {
workstationPrivate = import ./modules/workstation-private.nix;
};
homeModules = {
privateProfile = import ./home/private-profile.nix;
};
privateHostDefinitions = {
desktop = {
systemModules = [ nixosModules.workstationPrivate ];
homeModules = [ homeModules.privateProfile ];
};
laptop = {
systemModules = [ nixosModules.workstationPrivate ];
homeModules = [ homeModules.privateProfile ];
};
};
in
nix-config.lib.mkFlakeOutputs {
baseHostDefinitions = nix-config.hostDefinitions;
extraHostDefinitions = privateHostDefinitions;
};
}That pattern is supported by lib/mk-flake-outputs.nix: base host
definitions and private extraHostDefinitions are merged, and extra
systemModules and homeModules are appended. In practice this makes the
private repo behave like an overlay on top of the public host inventory.
If a companion repo eventually wants standalone Home Manager outputs, the same
builder also accepts baseHomeDefinitions and extraHomeDefinitions. Existing
host-overlay callers do not need to pass them; host-derived homes remain the
fallback when those attrs are omitted or empty.
When explicit home definitions are present, matching host-side homeModules
still append into the corresponding "<user>@<host>" home for compatibility
with companion repos that extend hosts through extraHostDefinitions.
That means a private companion repo can either:
- extend a public host such as
desktoporlaptop - add a private-only host by giving
extraHostDefinitionsa new host name
The example companion repo also includes:
examples/private-repo/modules/workstation-private.nix- example private NixOS overlayexamples/private-repo/home/private-profile.nix- example private Home Manager overlayexamples/private-repo/bin/rebuild- example rebuild helper for the companion repo
The example helper is used from the private repo, not from this public one:
./bin/rebuild desktopFor a fuller walkthrough of that layout, see examples/private-repo/README.md.