OFFSET偏移
← All articlesOFFSET / FIELD NOTESNO. 075

Declarative GNOME desktop management

Organize desktop, login, theme, and input-method configuration responsibilities into module groups.

English translation · Code and commands follow the Chinese original.

IN THESE READING PATHSA declarative GNOME desktop on NixOS ↗
About 3 min readStart reading

Verification scope: nixpkgs nixos-unstable modules and upstream documentation consulted in October 2026. Group membership, package counts, and service defaults change with revisions; when deploying, use the nixpkgs and Home Manager sources locked by your project as the authority. No builds, activations, or desktop runtime tests were performed for this article.

Declarative enablement#

services.desktopManager.gnome.enable = true;
services.displayManager.gdm.enable = true;

Behind these declarations is a whole set of group switches: GNOME on NixOS is split into package groups that can be enabled or disabled independently.

Module group switches (services.gnome.*)#

Switch Default What it controls
core-os-services Forced to true Service foundation: dconf, polkit, accounts-daemon, NetworkManager, xdg portal, power-profiles
core-shell Forced to true GNOME Shell itself: gnome-session + gnome-shell (systemd units), control-center, settings-daemon
core-apps true Default application suite (for example: nautilus, epiphany, calculator, weather, console…)
games false Small games (Mines, Sudoku, Chess…)
core-developer-tools false Developer tools (gnome-builder, dconf-editor, sysprof…)

So:

  • Minimal GNOME = core-apps.enable = false + exclude gnome-tour/gnome-user-docs (these two are in core-shell optionalPackages, not core-apps)
  • A more complete GNOME = enable core-apps and the developer tools/games you need (games can remain disabled as appropriate)

The large webkitgtk package Epiphany, the browser in core-apps, depends on webkitgtk, a very large package that is slow to build/download the first time. A minimal configuration omits it; a full installation comes with that cost.

GDM and the existing login setup#

  • GDM defaults to Wayland; starting with GNOME 50, Wayland cannot be disabled (the option has been removed)
  • GDM and kmscon are not inherently incompatible: in current nixpkgs, kmscon automatically avoids tty1 when GDM is enabled (the module’s mkIf (!displayManager.enable))
  • GDM reads registered wayland-sessions/*.desktop files. Hyprland, niri, and similar environments appear on the login screen only when their modules provide sessionPackages. Installing a binary alone does not guarantee that a session is registered.
  • Use specialisation to define system variants (see Building GNOME Variants with Specialisation), leaving the primary kmscon workflow unchanged

Centralized theme management#

Theme packages, dconf settings, and dark-mode scheduling need clear configuration ownership so desktop modules, Home Manager, and external schedulers do not repeatedly write the same key. For example:

  • home/theme.nix centrally manages GTK theme, icon, and cursor packages, and declares the dconf keys to write during activation.
  • If a scheduler such as Noctalia switches dark mode at runtime, explicitly give it responsibility for color-scheme, or accept that a later Home Manager activation will restore the declared value.
  • A GNOME specialisation that inherits the same Home Manager profile can share themes; the user’s HOME and dconf state also remain shared.

This lets multi-desktop configurations reuse theme declarations while making it clear which layer triggers each settings change.

Input method (fcitx5)#

  • GNOME Wayland uses text-input-v3: do not set GTK_IM_MODULE (the official recommendation; GTK uses the native protocol). Use QT_IM_MODULE=fcitx for older Qt versions or applications unable to use the native protocol. Check native protocol support against the actual version of newer Qt releases; XWayland uses XMODIFIERS=@im=fcitx
  • GNOME Shell limits candidate-window positioning for some toolkit/input-method module paths. You can use the kimpanel extension (pkgs.gnomeExtensions.kimpanel; enable it manually in the Extensions app after installation)
  • The GNOME module defaults to i18n.inputMethod.type = mkDefault "ibus"; an explicit "fcitx5" setting takes precedence

The practical value of grouping#

GNOME’s desktop entry points, service modules, and application lists are declared separately, letting you install default applications, developer tools, or extensions as needed. Modularity makes configuration ownership and dependencies easier to track, but does not prove that one desktop is necessarily more stable than another. When comparing GNOME, COSMIC, or other desktops, record specific versions, login paths, functional requirements, and runtime evidence rather than inferring stability directly from repository organization.

Related reading#

References & further reading

  1. Nixpkgs GNOME Module ↗
  2. Nixpkgs GNOME Documentation ↗
  3. Official Fcitx Wayland Documentation ↗
  4. GDM Module ↗
  5. kmscon Module ↗

Adapted from technical notes. Examples use generic names.

Continue along a reading path

A declarative GNOME desktop on NixOS

  1. 01Declarative GNOME desktop management
  2. 02GNOME module options reference
  3. 03Managing GSettings defaults and dconf state
  4. 04From settings diffs to declarations and extensions
  5. 05Building GNOME variants with Specialisation
  6. 06kmscon and uwsm in Wayland sessions
CONTINUE READING / NEXT ARTICLEGNOME module options reference

Trace module source code to clarify desktop entry points, service switches, application groups, and exclusion mechanisms.