Lallapallooza
simple_nix
Shellโœจ New

NixOS desktop config (Hyprland + Plasma 6) -- custom 10-group Neovim syntax highlighting and Ayu Dark theming across the full stack

Last updated Jul 3, 2026
36
Stars
4
Forks
1
Issues
0
Stars/day
Attention Score
40
Language breakdown
Shell 49.7%
Nix 25.7%
Lua 14.4%
Python 3.2%
Go 1.8%
TypeScript 1.7%
โ–ธ Files click to expand
README

NixOS Desktop Config

Modular NixOS configuration with Hyprland (UWSM) + Plasma 6 fallback, SDDM display manager.

Structure

nixos/                   # NixOS system config (flake-based)
  flake.nix              # inputs: nixpkgs-unstable, home-manager, agenix, lanzaboote
  host.nix               # machine-specific constants (edit for new PCs)
  configuration.nix      # entry point
  hardware.nix           # boot, kernel, NVIDIA, CPU, bluetooth
  hardware-configuration.nix  # auto-generated (nixos-generate-config)
  desktop.nix            # SDDM, Hyprland, Plasma, portals, audio, fonts
  security.nix           # SSH, PAM, gnome-keyring, agenix
  programs.nix           # system packages, steam, docker, flatpak
  auto-upgrade.nix       # nightly check for upstream updates + notification
  nordvpn.nix            # NordVPN daemon + GUI (FHS-wrapped from .deb)
  overlays/cli-tools.nix # br built from source (upstream flake is broken)
  home/                  # home-manager modules
scripts/
  install-ai-tools.sh    # native install of claude-code + codex to ~/.local/bin
  add-secret.sh          # add and wire up a new agenix secret
config/                  # dotfiles (most symlinked by link.sh)
  nvim/                  # Neovim (NvChad), symlinked
  hypr/                  # Hyprland user config, symlinked
  kitty/                 # terminal, symlinked
  hyprpanel/             # status bar, symlinked
  rofi/                  # app launcher, symlinked
  p10k/                  # Powerlevel10k prompt, symlinked
  clangd/                # clangd config, symlinked
  gtk-3.0/, gtk-4.0/     # GTK accent overrides (home-manager)
  mc/                    # Midnight Commander (home-manager)
  kde/                   # KDE color scheme (home-manager)
skills/                  # AI agent skills (see skills/README.md)
wallpapers/              # wallpaper images (gitignored)

Quick Start

0. Clone

git clone https://github.com/Lallapallooza/simple_nix.git
cd simple_nix

1. Edit nixos/host.nix

All machine-specific values live here:

{
  username = "my_username";
  # homeDir is derived as /home/${username} in flake.nix
  hostname = "nixos";
  timezone = "Europe/Dublin";
  defaultLocale = "en_US.UTF-8";
  regionalLocale = "en_IE.UTF-8";
  tmpfsSize = "16G";           # ~half of RAM
  steamScaling = "1.666667";   # match your monitor scale
  cursorSize = 24;             # 16@1x, 24@1.5x, 32@2x
  nvidia = true;               # false for AMD/Intel GPU
  repoDir = "/home/myusername/code/simplenix";  # local clone path (for update checks)
  autoUpgrade = true;          # nightly check for upstream updates (notifies, doesn't rebuild)
}

2. Edit config/hypr/user.conf

Hyprland config is plain text (not Nix), edit manually:

# Monitor
monitor = DP-4, 3840x2160@240, 0x0, 1.666667

^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^

connector resolution+hz scale factor

Scaling (must match your monitor scale)

env = XCURSOR_SIZE,24 env = HYPRCURSOR_SIZE,24 env = GDK_SCALE,2 env = GDKDPISCALE,0.8333

NVIDIA-specific (set to false/0 on AMD/Intel)

xwayland { forcezeroscaling = true } cursor { nohardwarecursors = true }

3. Build

./install.sh

Relog (SDDM) to pick up the new Hyprland session.

Known issues

  • Telegram steals focus on new messages -- Telegram's "Draw attention to the window" feature uses Wayland activation, which Hyprland treats as a focus request. Go to Telegram -> Settings -> Notifications -> disable Draw attention to the window. See hyprwm/Hyprland#9186.

Deployment

  • home-manager deploys mc and kde as nix store symlinks (./install.sh to apply)
  • link.sh symlinks everything else for live editing (no rebuild needed)

Dev Environment

  • nix-ld enabled -- pip wheels, npm native modules, and other binary packages just work
  • direnv for per-project environments -- drop a .envrc and tools auto-activate on cd:
# Python venv
  echo 'source .venv/bin/activate' > .envrc && direnv allow

# Nix shell echo 'use nix' > .envrc && direnv allow

  • Python: uv, basedpyright + ruff, Python 3.13. PyTorch wheels bundle their own CUDA runtime -- uv pip install torch works with nix-ld
  • C/C++: clang, clangd, cmake. NixOS pitfall -- clangd can't find standard headers without this in CMakeLists.txt:
set(CMAKEEXPORTCOMPILE_COMMANDS ON)   set(CMAKECXXSTANDARDINCLUDEDIRECTORIES ${CMAKECXXIMPLICITINCLUDEDIRECTORIES})
Then: ln -s build/compile_commands.json .
  • Rust: rustc, cargo, rust-analyzer
  • Go: go, gopls
  • JVM: JDK, Kotlin, kotlin-language-server
  • Neovim: NvChad-based, LSPs from nix (clangd, basedpyright, ruff, rust-analyzer, tsls, bashls), conform.nvim for formatting. See config/nvim/CHEATSHEET.md
  • AI coding tools: claude-code and codex install natively via scripts/install-ai-tools.sh (they update too often for OS rebuilds)
  • AMD uProf (optional, AMD CPUs only) -- microarchitectural profiler: IBS sampling, Zen PMU counters, cache/mem/branch/TLB events, power timechart. See AMD uProf setup
  • NVIDIA Nsight Graphics (optional, NVIDIA GPUs only) -- headless frame debugger and GPU profiler CLI for Vulkan/OpenGL/DirectX. See Nsight Graphics setup

Theme

Ayu Dark everywhere. One palette, every app.

Stock Ayu Dark looks great out of the box but collapses several semantic roles to the same color. Parameters and constants/numbers are both purple (#D2A6FF) -- you can't tell a function argument from a numeric literal. Properties and library functions share coral (#F07178). The two blues (#39BAE6 for built-in types and #59C2FF for user types) are hard to tell apart in practice.

This config fixes those collisions with a 10-group system. Parameters stay purple, but constants get their own muted gold (#C4B070). Properties move to mint (#80DDB8). Self/builtins get cyan (#39BAE6), clearly distinct from type blue (#59C2FF). The foreground is dimmed to #B8B5AC (stock is brighter #BFBDB6) so accent colors pop above the text ground level. Constants and operators are pushed below foreground brightness -- they recede so the important tokens stand out.

| Role | Hex | Used for | |------|-----|----------| | Background | #0B0E14 | kitty, hyprlock, hyprpanel, KDE, rofi | | Surface | #14171D | rofi bg-alt, hyprpanel cards, KDE Window bg | | Border | #1A1D23 | Hyprland inactive border, hyprpanel borders | | Foreground | #B8B5AC | kitty, hyprlock, hyprpanel, KDE, rofi | | Dimmed | #3D4046 | kitty bright-black, disabled states | | Accent | #FF8F40 | Hyprland borders, hyprlock, hyprpanel, kitty cursor, rofi, GTK, KDE | | Red | #F07178 | errors, destructive actions | | Green | #AAD94C | strings, success states | | Yellow | #E6C54C | warnings, functions (neovim) | | Blue | #59C2FF | types, links, info | | Purple | #D2A6FF | parameters, lifetimes | | Cyan | #39BAE6 | self/builtins | | Mint | #80DDB8 | properties, regex, special chars | | Orange | #FF7733 | keywords (neovim anchor color) |

Neovim: 10-group syntax highlighting

  • Keywords #FF7733 orange -- the anchor color everything else is tuned against
  • Functions #E6C54C gold -- warm but 22 degrees from keyword orange on the hue wheel
  • Strings #AAD94C green -- standard, distinct from everything
  • Types+Modules #59C2FF blue -- structs, classes, imports, tags
  • Constants #C4B070 muted gold -- intentionally dimmer than fg so they recede
  • Self/Builtins #39BAE6 cyan -- self, this, init
  • Properties #80DDB8 mint -- struct fields, object members
  • Parameters #D2A6FF purple -- function arguments, lifetimes
  • Decorators #E6C08A beige -- @decorator, #[attr], macros
  • Operators #CC7832 dark orange -- quiet scaffolding, doesn't compete with keywords
Design choices:
  • No italic anywhere -- keeps monospace grid clean
  • CVD-aware -- tested for mild red-green color vision deficiency; no meaning carried by red-green contrast alone
  • LSP semantic tokens enabled -- treesitter handles syntax, LSP adds type-level precision; empty @lsp.type.variable = {} lets treesitter's more specific groups show through
  • Foreground dimmed to #B8B5AC -- stock is brighter #BFBDB6; dimming gives accent colors more contrast

Desktop theming

Applied via:

  • kitty -- 16 terminal colors + cursor/selection in kitty.conf
  • KDE -- full Ayu Dark color scheme in kdeglobals (deployed by home-manager)
  • GTK 3/4 -- accent, destructive, success, warning, error overrides in gtk.css
  • rofi -- custom ayu-dark.rasi theme
  • hyprpanel -- custom config.json with Ayu Dark palette
  • hyprlock -- blurred background with Ayu Dark text/input colors
  • Hyprland -- border colors use accent orange

AMD uProf (optional)

AMD uProf isn't in nixpkgs -- AMD gates every download behind a EULA form, so no fetchurl is possible. The overlay at nixos/overlays/amduprof.nix handles it via requireFile: you download the tarball once, add it to the Nix store, set a flag, rebuild.

Gated by amduprof in host.nix. Leave it false (default) and install.sh works on any machine without the tarball.

One-time setup

# 1. Download AMDuProfLinuxx64_<version>.tar.bz2 (~300 MB) from:

https://www.amd.com/en/developer/uprof.html

(The version pinned in the overlay is 5.2.606 -- bump uprofVersion

there if you grab a newer release.)

2. Compute its hash and paste into uprofHash in

nixos/overlays/amduprof.nix:

nix hash file ~/Downloads/AMDuProfLinuxx64_5.2.606.tar.bz2

3. Add the tarball to the Nix store:

nix store add-file ~/Downloads/AMDuProfLinuxx64_5.2.606.tar.bz2

4. Enable the flag in nixos/host.nix:

amduprof = true;

5. Rebuild

./install.sh

Afterwards AMDuProfCLI, AMDuProfPcm, and AMDuProfCfg are on PATH. Quick check:

AMDuProfCLI info                                        # system/CPU info
AMDuProfCLI collect --config tbp -o /tmp/uprof ./myapp  # sample a binary
AMDuProfCLI report  -i /tmp/uprof/AMDuProf-*            # text report

No msr kernel-module changes are needed for user-space profiling on the default NixOS sysctls. If a specific counter errors with "Permission denied", run that single invocation with sudo -- CAPSYSADMIN bypasses the default paranoid level. If the wrapper complains about a missing .so, add the library to fhsDeps in the overlay and rebuild.

Instruction Based Sampling (IBS) and perfeventparanoid

IBS profile scopes require kernel.perfeventparanoid <= 1 for non-root users. NixOS defaults to 2, so AMDuProfCLI collect with an IBS config fails with:

ERROR: For non-root users, following perfeventparanoid values are valid
for Instruction Based Sampling:
        <= 1 : for all Instruction Based Sampling profile scopes.

Temporary (resets on reboot):

sudo sysctl -w kernel.perfeventparanoid=1

Persistent, add to nixos/configuration.nix:

boot.kernel.sysctl."kernel.perfeventparanoid" = 1;

Check the current value with cat /proc/sys/kernel/perfeventparanoid. Alternatively, run AMDuProfCLI collect under sudo -- root bypasses the paranoid check entirely.

NVIDIA Nsight Graphics (optional)

Nsight Graphics isn't in nixpkgs (only nsightcompute and nsightsystems are). NVIDIA gates the download behind a developer login, so no fetchurl is possible. The overlay at nixos/overlays/nsight-graphics.nix handles it via requireFile: it extracts the Makeself installer's pkg/ tree and wraps the headless CLI in a buildFHSEnv. The GUI (ngfx-ui) is intentionally skipped.

Gated by nsightGraphics in host.nix. Leave it false (default) and install.sh works on any machine without the installer.

One-time setup

# 1. Download NVIDIANsightGraphics<version>-linuxx64.run (~450 MB) from:

https://developer.nvidia.com/nsight-graphics

(The version pinned in the overlay is 2026.2.0.26134 -- bump

nsightVersion there if you grab a newer release.)

2. Compute its hash and paste into nsightHash in

nixos/overlays/nsight-graphics.nix:

nix hash file ~/Downloads/NVIDIANsightGraphics2026.2.0.26134-linuxx64.run

3. Add the installer to the Nix store:

nix store add-file ~/Downloads/NVIDIANsightGraphics2026.2.0.26134-linuxx64.run

4. Enable the flag in nixos/host.nix:

nsightGraphics = true;

5. Rebuild

./install.sh

Afterwards ngfx, ngfx-capture, and ngfx-replay are on PATH. Quick check:

ngfx --version                        # tool version
ngfx --help-all                       # general + per-activity options
ngfx --activity "GPU Trace Profiler" --exe ./myapp --output-dir /tmp/trace

The NVIDIA driver libraries reach the sandbox through /run/opengl-driver, which buildFHSEnv mounts automatically. If the wrapper complains about a missing .so, add the library to fhsDeps in the overlay and rebuild.

Secure Boot (dual-boot with Windows)

NixOS boots through Secure Boot via Lanzaboote, which signs systemd-boot stubs with custom keys. Microsoft's keys are kept alongside for Windows compatibility.

After a fresh install or on a new machine:

# 1. Generate Secure Boot signing keys
sudo nix-shell -p sbctl --run "sbctl create-keys"

2. Build and sign (keys must exist before rebuild)

./install.sh

3. Verify all boot entries are signed (kernel-* unsigned is expected)

sudo nix-shell -p sbctl --run "sbctl verify"

Then configure the BIOS (ASRock Taichi X870E shown, other boards similar):

4. Reboot into BIOS (F2/Del), Advanced Mode (F6)
  • Security > Secure Boot > Secure Boot Mode = Custom
  • Clear Secure Boot Keys > Yes
  • F10 save, boot back into NixOS
# 8. Enroll your keys + Microsoft's (--microsoft is mandatory for dual-boot)
sudo nix-shell -p sbctl --run "sbctl enroll-keys --microsoft"
9.  Reboot into BIOS (F2/Del)
  • Security > Secure Boot = Enabled
  • F10 save
# 12. Verify -- should show "Secure Boot: enabled (user)"
bootctl status

To boot Windows: press F11 at POST for the boot device menu, select the Windows drive. BitLocker will ask for the recovery key once after key enrollment, then re-seals automatically.

AI Coding Tools

claude-code and codex release too often to package in nix (an OS rebuild per bump). They install natively to ~/.local/bin (already on PATH via home-manager):

./scripts/install-ai-tools.sh          # install/update both
./scripts/install-ai-tools.sh codex    # just one

claude-code uses Anthropic's official installer and self-updates afterwards. codex installs from npm (@openai/codex, vendors static musl binaries that run on NixOS unpatched) with --prefix ~/.local; rerun the script to update it.

br is built from source in nixos/overlays/cli-tools.nix because its upstream flake is broken.

The nightly update check (nixos/auto-upgrade.nix) is enabled by default (autoUpgrade = true in host.nix). It fetches origin/main and notifies you (shell login + desktop notification) if your local branch is behind. You rebuild manually with ./install.sh. Set to false to disable.

Secrets

Secrets are managed with agenix -- age-encrypted files committed to the repo. Ciphertext is safe to publish; only holders of the private key can decrypt.

Two decryption keys are configured in nixos/secrets/secrets.nix:

  • Personal age key -- portable, stored in a password manager. Use this to bootstrap new machines.
  • Machine host key -- per-machine SSH host key for unattended decryption at boot.

Using your own secrets

To use this config with your own secrets:

# 1. Generate a personal age key (store the private key in your password manager!)
age-keygen -o ~/.config/age/keys.txt

2. Get your machine's host key

cat /etc/ssh/sshhosted25519_key.pub

3. Edit nixos/secrets/secrets.nix -- replace both keys with yours

vitalii = "age1..."; <-- your age public key (from step 1)

nixos = "ssh-ed25519 AAAA..."; <-- your host key (from step 2)

4. Create your GitHub SSH key secret

cd nixos/secrets agenix -e ided25519github.age -i ~/.config/age/keys.txt

(paste your GitHub SSH private key, save)

5. Build

./install.sh

Adding a new machine

# On the new machine:

1. Copy your personal age key from password manager to ~/.config/age/keys.txt

2. Add the new machine's host key to nixos/secrets/secrets.nix

cat /etc/ssh/sshhosted25519_key.pub

3. Re-encrypt all secrets for the new recipient (from any machine that can decrypt)

cd nixos/secrets && agenix -r -i ~/.config/age/keys.txt

4. Commit, push, then install on the new machine

./install.sh

Adding more secrets

# Interactive: prompts for the secret value (hidden input)
./scripts/add-secret.sh my-api-key

It will:

1. Encrypt the value to nixos/secrets/my-api-key.age

2. Add the entry to secrets.nix automatically

3. Wire it up in security.nix

Then apply

./install.sh

Wallpaper

Place a wallpaper image in wallpapers/wallpaper.png (gitignored). link.sh will symlink it to ~/Pictures/wallpaper.png, where hyprpaper picks it up.

To use a different image, replace the file or edit config/hypr/hyprpaper.conf.

๐Ÿ”— More in this category

ยฉ 2026 GitRepoTrend ยท Lallapallooza/simple_nix ยท Updated daily from GitHub