My NixOS Configuration!

Table of Contents

A reproducible, modular NixOS desktop configuration featuring Hyprland, Ghostty, Emacs, and a complete development toolchain — all managed via flake and home-manager.

screenshot_20260510_173031.png

screenshot_20260510_171024.png

screenshot_20260510_171035.png

screenshot_20260509_125220.png

screenshot_20260509_125139.png

screenshot_20260509_125317.png

screenshot_20260509_125943.png

screenshot_20260509_124026.png

screenshot_20260510_170940.png

I spent two days to move my previous linux configuration and development environments into NixOS. This document records the setup and serves as a reference for anyone interested in NixOS-based desktop configuration.

1. What is NixOS?

NixOS is a special Linux distro built upon the Nix.

So what is Nix?

Nix is:

  • A functional programming language, and a DSL for addressing the configuration problems.
  • A package management tool.
  • An OS.

Core idea of Nix/NixOS:

  • Anything of a SYSTEM can be described, and thus, thanks to the feature of functional definition, it can be easily reproduced.
  • Similar to git, Nix/NixOS employ a more efficient way to manage different package versions and corresponding dependencies, where two different version of the same program can be coexistent with each other.
  • Different from the snapshot, NixOS allows to boot under any version of the NixOS BUILD, which demonstrate that a man will not be worried about any OS crash.

Why I use it:

  • I'd like to keep the configuration be 可积累的
  • I enjoy this way, just like why I like to use emacs.

2. What This Configuration Contains?

This configuration contains a minimal configuration of my new desktop environment.

It is a TTY environment by default, BUT providing a very beautiful and robust and convenient DESKTOP development environment.

The schema as list below:

Component Solution
System NixOS (26.05)
Use Flake? Yes
Default OS Env TTY
Desktop Env Wayland
Desktop Hyprland
Launcher wofi
Status Bar waybar
Terminal ghostty*
File Manager nemo*
Notifications dunst/libnotify
GTK juno-theme
Icon beauty-line-icon
Capture grim/slurp/swappy
Wallpaper awww
Editor emacs/vim
Agent opencode
VPN/Proxy clash-verge-rev

Note: This list will keep increase and changed dynamically.

2.1. Chinese Input & Communication

  • Input Method: fcitx5 with rime and pinyin, theme Material-Color-deepPurple
  • Communication: wechat-uos, qq

2.2. Emacs

Emacs is pulled from the emacs-overlay, providing the latest emacs-unstable-pgtk build with native Wayland support. The Emacs configuration is auto-cloned from a.emacs.d via home.activation during first rebuild.

3. Repository Structure

The full source is at github.com/liangzid/NixConfig.

nix-config/
├── flake.nix                 # Entry point — defines inputs and NixOS config
├── flake.lock                # Pinned input versions
├── bootstrap.sh              # Install / apply / build-ISO
├── hosts/
│   └── nixos/
│       ├── configuration.nix # System-level config (boot, users, packages, ssh)
│       ├── hardware-configuration.nix
│       └── home.nix          # User-level config (packages, env, dotfiles, ssh)
├── modules/
│   ├── system/               # Reusable system modules
│   │   ├── hyprland.nix      # Hyprland WM with xwayland
│   │   ├── nvidia.nix        # NVIDIA GPU + modesetting
│   │   ├── fonts.nix         # CJK + nerd fonts
│   │   ├── input-method.nix  # fcitx5 + rime + cloudpinyin + theme
│   │   ├── pipewire.nix      # Audio: pipewire + alsa + pulse
│   │   ├── portal.nix        # XDG desktop portal for Wayland
│   │   └── kanata.nix        # CapsLock → Control remap
│   └── home/                 # Reusable home-manager modules
│       ├── emacs.nix          # Emacs + vterm
│       ├── waybar.nix        # Status bar with tokyonight theme
│       └── gtk.nix           # GTK theme + dark mode
└── dotfiles/                 # Configuration files managed by home-manager
    ├── hypr/hyprland.conf    # Hyprland keybindings + autostart
    ├── wofi/{config,style.css}
    ├── ghostty/config        # Terminal with Emacs-style keybinds + Aura theme
    ├── clash/merge-hk.yaml   # GFW bypass rules (Hong Kong mode)
    ├── clash/merge-cn.yaml   # GFW bypass rules (Mainland mode)
    └── fcitx5/{classicui,pinyin}.conf  # Input method theming & behaviour

4. Getting Started

4.1. On an Existing NixOS Machine

git clone https://github.com/liangzid/nix-config.git ~/code/NixConfig
sudo nixos-rebuild switch --flake ~/code/NixConfig#nixos

4.2. Fresh Install (from NixOS ISO)

# 1. Partition disks and mount to /mnt
# 2. Run the installer
./bootstrap.sh install

This will generate a hardware config for the new machine, clone the repo, and run nixos-install --flake.

4.3. Tip: Quick Rebuild

Use the update alias:

update

Remember to git add any newly created files before rebuilding, as the flake requires all referenced files to be Git-tracked.

5. Hyprland Keybindings

Key Action
Super + arrows Move focus
Super + Tab Cycle windows
Super + 1-0 Switch to workspace 1-10
Super + Shift + 1-0 Move window to workspace 1-10
Super + K Kill active window
Super + V Toggle floating
Super + F Toggle fullscreen
Super + R Enter resize mode (arrows / HJKL)
Super + T Open terminal (ghostty)
Super + X Open launcher (wofi)
Super + E Open file manager (nemo)
Super + L Lock screen (swaylock)
Super + Q Quit Hyprland
Super + Alt + arrows Move window
Ctrl + Alt + T Open terminal (alternative)
Print Screenshot region → annotate
Ctrl + Print Fullscreen screenshot → clipboard

6. Ghostty Keybindings

Ghostty is the primary terminal emulator, configured with Emacs-style keybinding conventions.

Key Action
C-x 2 Split horizontally (down)
C-x 3 Split vertically (right)
C-x 1 Zoom (maximize) current split
C-x 0 Close current split
C-x o Next split (other-window)
C-x k Close current split
C-x b Tab overview
Alt + 1-9 Jump to tab 1-9
Ctrl+Shift+T / C-t New tab
Ctrl+Shift+W Close surface
Ctrl+Shift+Enter New split (auto direction)
Ctrl+Shift+, Reload config

Ghostty uses the Aura theme with background-opacity = 0.8 and term = xterm-256color for full compatibility when SSH-ing to remote servers.

7. Laboratory Server Access

All SSH servers are defined in the home.nix configuration. Each server has two aliases:

  • gsXX / csX — direct connection
  • gsXXo / csXo — via bastion (jump host: is1.astaple.com)
ssh gs14       # direct
ssh gs14o      # via jump host
ssh cs1        # direct
ssh cs2o       # via jump host

SSH keepalive (ServerAliveInterval 60) prevents idle disconnection, and AddKeysToAgent yes caches key passphrases in memory.

8. GFW Bypass (Clash Verge Rev)

clash-verge-rev is installed for proxy management. Two merge configs are provided for switching between regions:

  • merge-hk.yaml: most traffic → DIRECT, only AI services (ChatGPT, OpenAI, Anthropic) → Proxy
  • merge-cn.yaml: subscription handles default routing, with additional rules for lab servers and AI services

To switch: Profiles → subscription → Edit Info → Merge → point to the desired yaml.

9. Input Method

Fcitx5 is configured with:

  • Chinese addons (pinyin + cloud pinyin)
  • Rime support
  • Theme: Material-Color-deepPurple
  • Shuangpin: Ziranma profile
  • Complete pinyin.conf managed by home-manager

10. Keyboard Remap

CapsLock is remapped to Control via kanata.

11. System Aliases

Alias Command
enw emacs -nw
ec emacsclient
update sudo nixos-rebuild switch --flake ~/code/NixConfig#nixos
latexmain latexmk --pdflatex main.tex
gui start-hyprland

12. Notes

12.1. Super+L and logind

Systemd-logind intercepts Super+L by default. This config adds services.logind.settings to ignore those hardware keys and let Hyprland handle them.

12.2. Swaylock PAM

Swaylock is configured as a PAM service (security.pam.services.swaylock) so it can unlock the screen without requiring a password policy override.

12.3. Steam

Steam is enabled at the system level: programs.steam.enable = true. This automatically installs all required 32-bit libraries and the Steam package itself.

12.4. Ghostty Terminfo

Ghostty's terminfo is made available via environment.sessionVariables.TERMINFO_DIRS. Additionally, term = xterm-256color in the Ghostty config ensures full compatibility when SSH-ing to remote servers that lack the Ghostty terminfo entry.

12.5. Unfree Packages

nixpkgs.config.allowUnfreePredicate whitelists only the unfree packages actually in use (NVIDIA drivers, Steam, Discord, VS Code, WeChat, QQ, etc.).

12.6. Git Requirement

The flake requires all referenced files to be tracked by Git. Before rebuilding, run:

git -C ~/code/NixConfig add -A

Author: Zi Liang (zi1415926.liang@connect.polyu.hk) Create Date: Sun May 10 16:51:14 2026 Last modified: 2026-05-12 Tue 20:20 Creator: Emacs 30.2 (Org mode 9.7.11)