Skip to content

sk4rd/nix-config

Repository files navigation

nix-config

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

Start here

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 show

Apply a full NixOS host configuration:

sudo nixos-rebuild switch --flake .#desktop

Apply only the Home Manager configuration:

home-manager switch --flake .#miko@desktop

If home-manager is not already in PATH, use:

nix run nixpkgs#home-manager -- switch --flake .#miko@desktop

If 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-link

Format Nix files:

nix fmt

Replace desktop and miko@desktop with any other output name shown by nix flake show.

Repository layout

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 both desktop and laptop.
  • modules/users/ - shared system user modules reused by host-specific user wiring.
  • modules/wsl/ - reusable WSL system module for the public wsl host 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 the miko@wsl output.
  • 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:

  • desktop and laptop both import profiles/workstation/, which now includes the shared Stylix policy for workstation hosts.
  • desktop and laptop both use home/miko/ as their personal base home module through public-host-definitions.nix.
  • The host-specific user modules in hosts/desktop/user.nix, hosts/laptop/user.nix, and hosts/wsl/user.nix all build on the shared base user module in modules/users/miko.nix.
  • home/default.nix now imports the shared CLI layer, while workstation homes opt into the shared GUI layer through home/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.nix and home/miko/laptop.nix and are attached through public-host-definitions.nix.
  • wsl uses hosts/wsl/ and home/wsl/, which overlays WSL-specific settings on top of home/miko/base.nix and the shared CLI layer.

Changing the public repo

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:

  • hostPath for the NixOS module path
  • home for the default Home Manager user linked to that host
  • homeModules for extra Home Manager modules appended to that linked home
  • systemModules for extra NixOS modules
  • system for the target platform
  • wsl = true for 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:

  • username for the Home Manager username
  • path for the Home Manager module path
  • homeDirectory to override the default /home/<username> when needed
  • system for the target platform
  • homeModules for 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:

  • hostPath is picked field-by-field, so an extra definition replaces the base value when it sets one.
  • system behaves the same way as hostPath: extra wins if set, otherwise the base value is kept.
  • home is merged field-by-field for username, path, and homeDirectory; extra values override only the fields they set.
  • wsl is OR-ed, so once either side sets wsl = true, the merged host remains WSL-enabled.
  • systemModules are appended as (base.systemModules or [ ]) ++ (extra.systemModules or [ ]).
  • homeModules are 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:

  • username
  • path
  • homeDirectory
  • system
  • homeModules

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 ownership

Stylix is intentionally split by responsibility:

  • themes/one-dark.nix owns the shared palette, wallpaper, fonts, cursor, icons, and opacity defaults.
  • profiles/workstation/stylix.nix owns workstation system-side theme policy and disables Stylix's automatic Home Manager import.
  • home/miko/stylix.nix owns Home Manager-side target selection and manual program overrides such as Waybar, Mako, Hyprlock, Foot, and Zathura.
  • public-host-definitions.nix only 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.

Shared Zsh

The shared Zsh setup is also split by responsibility:

  • lib/shared-zsh-config.nix is the shared source of aliases and interactive shell helpers.
  • home/common/zsh.nix is the Home Manager entry point and adds Home Manager-specific integrations such as programs.fzf.enableZshIntegration, programs.zoxide.enableZshIntegration, and the lf shell helper.
  • modules/shared-zsh.nix is 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.

WSL integration

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.conf defaults for automount, interop, and generated networking files
  • nixConfig.wsl.automount.uid and nixConfig.wsl.automount.gid options 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, and gpg
  • optional use of the Windows OpenSSH agent pipe through SSH_AUTH_SOCK
  • a WSL-aware wsl-open command 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.nix marks the public wsl host with wsl = true, which makes the flake builder add the upstream nixos-wsl module.
  • modules/wsl/system.nix owns the public repo's WSL policy and sets wsl.enable = lib.mkDefault true so hosts importing it normally do not need to repeat that toggle.
  • modules/wsl/home.nix owns the reusable WSL Home Manager policy and is exported as homeModules.wsl.
  • hosts/wsl/default.nix imports the public WSL module plus local host/user wiring, but no longer repeats wsl.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@wsl

Hybrid 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

Private companion repo

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 desktop or laptop
  • add a private-only host by giving extraHostDefinitions a new host name

The example companion repo also includes:

  • examples/private-repo/modules/workstation-private.nix - example private NixOS overlay
  • examples/private-repo/home/private-profile.nix - example private Home Manager overlay
  • examples/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 desktop

For a fuller walkthrough of that layout, see examples/private-repo/README.md.

About

This is a MIRROR from my private Forgejo repo.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors