Agent Skill
2/7/2026

gnome

GNOME Skill

O
olafkfreund
10GitHub Stars
1Views
npx skills add olafkfreund/nixos_config

SKILL.md

Namegnome
DescriptionGNOME Skill

name: gnome version: 1.0 description: GNOME Skill

GNOME Skill

Overview

GNOME is a modern, full-featured desktop environment for NixOS. This skill provides comprehensive guidance for configuring GNOME declaratively using NixOS and Home Manager, with deep integration of Stylix theming, extension management, and best practices for a reproducible desktop experience.

Key Capabilities

  • Declarative configuration: Everything defined in Nix configuration files
  • Stylix integration: Automatic theming across all GNOME applications
  • Extension management: Reproducible extension installation and configuration
  • dconf settings: Complete control over GNOME preferences
  • GDM customization: Display manager and login screen theming
  • GTK theming: Consistent look across GTK3/GTK4 applications
  • Troubleshooting: Debug and fix common GNOME configuration issues

Why This Matters

Traditional GNOME configuration is imperative (click settings, install extensions manually). NixOS enables declarative GNOME configuration, making your desktop environment:

  • ✅ Reproducible across machines
  • ✅ Version controlled
  • ✅ Easy to backup and restore
  • ✅ Documented in code
  • ✅ Consistent with system configuration philosophy

Installation

Basic GNOME Setup (NixOS 25.11+)

# configuration.nix
{ pkgs, ... }:
{
  # Enable GDM and GNOME
  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  # Note: GNOME uses Wayland by default
  # Xwayland is included for compatibility
}

Legacy Setup (Pre-25.11)

# For older NixOS versions
{
  services.xserver = {
    enable = true;
    displayManager.gdm.enable = true;
    desktopManager.gnome.enable = true;
  };
}

Minimal GNOME (No Bloat)

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

  # Disable default applications
  services.gnome = {
    core-apps.enable = false;          # gnome-calculator, gnome-calendar, etc.
    core-developer-tools.enable = false; # gnome-builder, etc.
    games.enable = false;               # gnome-chess, etc.
  };

  # Exclude specific packages
  environment.gnome.excludePackages = with pkgs; [
    gnome-tour
    gnome-connections
    epiphany  # GNOME Web
    geary     # Email client
  ];

  # Install only what you need
  environment.systemPackages = with pkgs; [
    gnome-tweaks
    dconf-editor
    gnome-extension-manager
  ];
}

Home Manager Integration

Basic Setup

# home.nix
{ config, pkgs, ... }:
{
  # Enable dconf for GNOME settings
  dconf.enable = true;

  # GTK configuration
  gtk = {
    enable = true;

    gtk3.extraConfig = {
      gtk-application-prefer-dark-theme = true;
    };

    gtk4.extraConfig = {
      gtk-application-prefer-dark-theme = true;
    };
  };
}

Complete Home Manager Configuration

{ config, pkgs, lib, ... }:
{
  dconf = {
    enable = true;
    settings = {
      # Desktop interface
      "org/gnome/desktop/interface" = {
        color-scheme = "prefer-dark";
        enable-hot-corners = false;
        clock-show-weekday = true;
        clock-show-seconds = true;
        show-battery-percentage = true;
      };

      # Window manager
      "org/gnome/desktop/wm/preferences" = {
        button-layout = "appmenu:minimize,maximize,close";
        num-workspaces = 4;
        workspace-names = [ "Main" "Work" "Media" "Misc" ];
      };

      # Keybindings
      "org/gnome/desktop/wm/keybindings" = {
        close = [ "<Super>q" ];
        toggle-fullscreen = [ "<Super>f" ];
        switch-to-workspace-left = [ "<Control><Alt>Left" ];
        switch-to-workspace-right = [ "<Control><Alt>Right" ];
      };

      # Mouse and touchpad
      "org/gnome/desktop/peripherals/mouse" = {
        accel-profile = "flat";
        speed = 0.0;
      };

      "org/gnome/desktop/peripherals/touchpad" = {
        tap-to-click = true;
        two-finger-scrolling-enabled = true;
        natural-scroll = false;
      };

      # Favorite apps
      "org/gnome/shell" = {
        favorite-apps = [
          "org.gnome.Nautilus.desktop"
          "firefox.desktop"
          "kitty.desktop"
          "code.desktop"
        ];
      };
    };
  };
}

Stylix Integration

Basic Stylix Configuration

# configuration.nix
{ pkgs, inputs, ... }:
{
  imports = [
    inputs.stylix.nixosModules.stylix
  ];

  stylix = {
    enable = true;

    # Base16 color scheme
    base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-medium.yaml";

    # Wallpaper
    image = ./wallpapers/gruvbox.png;

    # Font configuration
    fonts = {
      monospace = {
        package = pkgs.nerdfonts.override { fonts = [ "JetBrainsMono" ]; };
        name = "JetBrainsMono Nerd Font Mono";
      };
      sansSerif = {
        package = pkgs.inter;
        name = "Inter";
      };
      serif = {
        package = pkgs.merriweather;
        name = "Merriweather";
      };
    };

    # Cursor theme
    cursor = {
      package = pkgs.bibata-cursors;
      name = "Bibata-Modern-Classic";
      size = 24;
    };

    # Opacity
    opacity = {
      terminal = 0.9;
      applications = 1.0;
    };

    # Enable GNOME targets
    targets = {
      gnome.enable = true;
      gtk.enable = true;
    };
  };

  # Additional GNOME setup
  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;
}

Advanced Stylix + GNOME

{ config, pkgs, lib, inputs, ... }:
{
  stylix = {
    enable = true;
    base16Scheme = "${pkgs.base16-schemes}/share/themes/tokyo-night-dark.yaml";
    image = ./wallpaper.png;

    # Polarity control
    polarity = "dark";

    # Font configuration
    fonts = {
      monospace = {
        package = pkgs.jetbrains-mono;
        name = "JetBrains Mono";
      };
      sansSerif = {
        package = pkgs.cantarell-fonts;
        name = "Cantarell";
      };
      sizes = {
        applications = 11;
        desktop = 10;
        popups = 10;
      };
    };

    # Targets
    targets = {
      gnome.enable = true;
      gtk.enable = true;
      console.enable = true;
    };
  };

  # Home Manager integration
  home-manager.users.myuser = { pkgs, config, ... }: {
    # Stylix automatically configures GTK
    # Additional GNOME-specific tweaks
    dconf.settings = {
      # Use Stylix colors in GNOME
      "org/gnome/desktop/interface" = {
        color-scheme = "prefer-dark";
        gtk-theme = lib.mkForce "Adwaita-dark";
        icon-theme = "Papirus-Dark";
      };

      # GNOME Shell theme (requires user-theme extension)
      "org/gnome/shell/extensions/user-theme" = {
        name = "Adwaita-dark";
      };
    };

    # Additional packages for theming
    home.packages = with pkgs; [
      papirus-icon-theme
      gnomeExtensions.user-themes
    ];
  };
}

Stylix Color Access in GNOME

{ config, lib, ... }:
{
  # Access Stylix colors for custom GNOME configuration
  dconf.settings = {
    "org/gnome/desktop/background" = {
      # Use solid color from theme
      picture-uri = "";
      primary-color = config.lib.stylix.colors.base00;
    };

    "org/gnome/terminal/legacy/profiles:/:b1dcc9dd-5262-4d8d-a863-c897e6d979b9" = {
      background-color = "rgb(${config.lib.stylix.colors.base00-rgb-r},${config.lib.stylix.colors.base00-rgb-g},${config.lib.stylix.colors.base00-rgb-b})";
      foreground-color = "rgb(${config.lib.stylix.colors.base05-rgb-r},${config.lib.stylix.colors.base05-rgb-g},${config.lib.stylix.colors.base05-rgb-b})";
    };
  };
}

Extension Management

Installing Extensions

# configuration.nix or home.nix
{ pkgs, ... }:
{
  home.packages = with pkgs.gnomeExtensions; [
    # Productivity
    dash-to-dock
    appindicator
    clipboard-indicator
    gsconnect

    # Visual
    blur-my-shell
    just-perfection
    user-themes

    # Window management
    tiling-assistant
    window-list

    # System
    vitals
    caffeine
  ];
}

Enabling Extensions via dconf

{ pkgs, ... }:
{
  dconf.settings = {
    "org/gnome/shell" = {
      disable-user-extensions = false;

      enabled-extensions = with pkgs.gnomeExtensions; [
        blur-my-shell.extensionUuid
        dash-to-dock.extensionUuid
        appindicator.extensionUuid
        clipboard-indicator.extensionUuid
        just-perfection.extensionUuid
        user-themes.extensionUuid
        tiling-assistant.extensionUuid
        vitals.extensionUuid
      ];
    };
  };
}

Configuring Extension Settings

{
  dconf.settings = {
    # Dash to Dock
    "org/gnome/shell/extensions/dash-to-dock" = {
      dock-position = "BOTTOM";
      dash-max-icon-size = 48;
      show-trash = false;
      show-mounts = false;
      intellihide-mode = "FOCUS_APPLICATION_WINDOWS";
      hot-keys = false;
    };

    # Blur My Shell
    "org/gnome/shell/extensions/blur-my-shell" = {
      brightness = 0.75;
      sigma = 30;
    };

    # Just Perfection
    "org/gnome/shell/extensions/just-perfection" = {
      panel = true;
      activities-button = false;
      app-menu = false;
      clock-menu-position = 1;  # Center
      workspace-switcher-should-show = true;
    };

    # Tiling Assistant
    "org/gnome/shell/extensions/tiling-assistant" = {
      enable-tiling-popup = false;
      window-gap = 8;
    };

    # Vitals
    "org/gnome/shell/extensions/vitals" = {
      hot-sensors = [
        "_processor_usage_"
        "_memory_usage_"
        "_temperature_processor_"
      ];
    };
  };
}

Complete GNOME Configuration Examples

Example 1: Developer Workstation

{ config, pkgs, lib, ... }:
{
  # System configuration
  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  # Minimal GNOME
  services.gnome.core-apps.enable = false;
  environment.gnome.excludePackages = with pkgs; [
    gnome-tour
    epiphany
    geary
  ];

  # System packages
  environment.systemPackages = with pkgs; [
    gnome-tweaks
    dconf-editor
    gnome-extension-manager
  ];

  # Home Manager
  home-manager.users.dev = { pkgs, ... }: {
    dconf = {
      enable = true;
      settings = {
        # Interface
        "org/gnome/desktop/interface" = {
          color-scheme = "prefer-dark";
          enable-hot-corners = false;
          show-battery-percentage = true;
        };

        # Window management
        "org/gnome/desktop/wm/preferences" = {
          num-workspaces = 6;
          workspace-names = [ "Code" "Browser" "Terminal" "Docs" "Chat" "Music" ];
        };

        # Keybindings
        "org/gnome/settings-daemon/plugins/media-keys" = {
          custom-keybindings = [
            "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
          ];
        };

        "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
          binding = "<Super>Return";
          command = "kitty";
          name = "Launch Terminal";
        };

        # Extensions
        "org/gnome/shell" = {
          disable-user-extensions = false;
          enabled-extensions = with pkgs.gnomeExtensions; [
            dash-to-dock.extensionUuid
            vitals.extensionUuid
            clipboard-indicator.extensionUuid
          ];
          favorite-apps = [
            "code.desktop"
            "firefox.desktop"
            "kitty.desktop"
            "org.gnome.Nautilus.desktop"
          ];
        };
      };
    };

    home.packages = with pkgs.gnomeExtensions; [
      dash-to-dock
      vitals
      clipboard-indicator
    ];
  };
}

Example 2: Media/Creative Workstation

{ config, pkgs, inputs, ... }:
{
  # Stylix theming
  stylix = {
    enable = true;
    base16Scheme = "${pkgs.base16-schemes}/share/themes/catppuccin-mocha.yaml";
    image = ./creative-wallpaper.jpg;

    fonts = {
      monospace = {
        package = pkgs.fira-code;
        name = "Fira Code";
      };
      sansSerif = {
        package = pkgs.inter;
        name = "Inter";
      };
    };

    targets = {
      gnome.enable = true;
      gtk.enable = true;
    };
  };

  # GNOME with full apps
  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  # Home Manager
  home-manager.users.creative = { pkgs, ... }: {
    dconf.settings = {
      # Visual tweaks
      "org/gnome/desktop/interface" = {
        color-scheme = "prefer-dark";
        gtk-theme = "Adwaita-dark";
        icon-theme = "Papirus-Dark";
      };

      # Workspaces for different tasks
      "org/gnome/desktop/wm/preferences" = {
        num-workspaces = 4;
        workspace-names = [ "Edit" "Preview" "Assets" "Reference" ];
      };

      # Extensions
      "org/gnome/shell" = {
        disable-user-extensions = false;
        enabled-extensions = with pkgs.gnomeExtensions; [
          blur-my-shell.extensionUuid
          just-perfection.extensionUuid
          user-themes.extensionUuid
        ];
      };

      # Blur My Shell for aesthetics
      "org/gnome/shell/extensions/blur-my-shell" = {
        brightness = 0.8;
        sigma = 40;
        blur-panel = true;
        blur-overview = true;
      };
    };

    home.packages = with pkgs; [
      papirus-icon-theme
      gnomeExtensions.blur-my-shell
      gnomeExtensions.just-perfection
      gnomeExtensions.user-themes
    ];
  };
}

Example 3: Minimal Tiling Setup

{ config, pkgs, ... }:
{
  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  # Minimal install
  services.gnome.core-apps.enable = false;

  home-manager.users.user = { pkgs, ... }: {
    dconf.settings = {
      # Minimal interface
      "org/gnome/desktop/interface" = {
        enable-hot-corners = false;
        show-battery-percentage = true;
      };

      # Remove top bar elements
      "org/gnome/shell/extensions/just-perfection" = {
        activities-button = false;
        app-menu = false;
        panel-in-overview = false;
      };

      # Tiling configuration
      "org/gnome/shell/extensions/tiling-assistant" = {
        enable-tiling-popup = false;
        window-gap = 4;
        single-screen-gap = 4;
        tiling-popup-all-workspace = true;
        enable-advanced-experimental-features = true;
      };

      # Extensions
      "org/gnome/shell" = {
        disable-user-extensions = false;
        enabled-extensions = with pkgs.gnomeExtensions; [
          tiling-assistant.extensionUuid
          just-perfection.extensionUuid
          appindicator.extensionUuid
        ];
      };
    };

    home.packages = with pkgs.gnomeExtensions; [
      tiling-assistant
      just-perfection
      appindicator
    ];
  };
}

Golden Path: Best Practices

1. Use Home Manager for User Settings

# ✅ CORRECT: Home Manager manages user settings
home-manager.users.alice = {
  dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
};

# ❌ WRONG: System-level user settings
programs.dconf.profiles.user.databases = [
  {
    settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
  }
];

Why: User settings belong in Home Manager, system settings in NixOS configuration.

2. Enable Extensions via dconf

# ✅ CORRECT: Declarative extension enablement
{
  dconf.settings."org/gnome/shell" = {
    disable-user-extensions = false;
    enabled-extensions = with pkgs.gnomeExtensions; [
      dash-to-dock.extensionUuid
    ];
  };

  home.packages = [ pkgs.gnomeExtensions.dash-to-dock ];
}

# ❌ WRONG: Just installing without enabling
{
  home.packages = [ pkgs.gnomeExtensions.dash-to-dock ];
  # Extension won't be active!
}

Why: Extensions must be explicitly enabled via dconf to function.

3. Use Stylix for Consistent Theming

# ✅ CORRECT: Let Stylix handle themes
{
  stylix = {
    enable = true;
    base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-medium.yaml";
    targets.gnome.enable = true;
    targets.gtk.enable = true;
  };
}

# ❌ WRONG: Manual theme configuration everywhere
{
  gtk.theme.name = "Adwaita-dark";
  dconf.settings."org/gnome/desktop/interface".gtk-theme = "Adwaita-dark";
  # Inconsistent, hard to maintain
}

Why: Stylix provides centralized, consistent theming across all applications.

4. Discover Settings with dconf watch

# ✅ CORRECT: Discover the right dconf paths
$ dconf watch /
# Change setting in GNOME Settings
# Output shows: /org/gnome/desktop/interface/show-battery-percentage

# Then add to config:
dconf.settings."org/gnome/desktop/interface".show-battery-percentage = true;

# ❌ WRONG: Guessing paths
dconf.settings."org/gnome/battery".show-percentage = true;  # Doesn't exist!

Why: dconf paths are not always intuitive; discovery prevents errors.

5. Organize Settings Logically

# ✅ CORRECT: Grouped by function
{
  dconf.settings = {
    # Interface
    "org/gnome/desktop/interface" = { /* ... */ };

    # Window management
    "org/gnome/desktop/wm/preferences" = { /* ... */ };
    "org/gnome/desktop/wm/keybindings" = { /* ... */ };

    # Peripherals
    "org/gnome/desktop/peripherals/mouse" = { /* ... */ };
    "org/gnome/desktop/peripherals/touchpad" = { /* ... */ };

    # Extensions
    "org/gnome/shell" = { /* ... */ };
    "org/gnome/shell/extensions/dash-to-dock" = { /* ... */ };
  };
}

Why: Maintainability and readability improve with logical organization.

6. Pin Extension Versions

# ✅ CORRECT: Explicit version pinning
{
  home.packages = [
    (pkgs.gnomeExtensions.dash-to-dock.overrideAttrs (old: {
      version = "87";
    }))
  ];
}

# ⚠️ CAUTION: Latest version may break
{
  home.packages = [ pkgs.gnomeExtensions.dash-to-dock ];
  # May update unexpectedly
}

Why: GNOME Shell API changes can break extensions; pinning ensures stability.

7. Use lib.mkForce Sparingly

# ✅ CORRECT: Let Stylix manage, override only when necessary
{
  stylix.targets.gtk.enable = true;

  # Only override if you have a specific reason
  gtk.theme.name = lib.mkForce "Adwaita-dark";
}

# ❌ WRONG: Overriding everything defeats declarative benefits
{
  gtk.theme.name = lib.mkForce "CustomTheme";
  gtk.iconTheme.name = lib.mkForce "CustomIcons";
  # Harder to maintain, Stylix integration broken
}

Why: mkForce breaks Stylix integration and reduces reproducibility.

8. Test Configuration Incrementally

# ✅ CORRECT: Test before committing
$ home-manager switch
# Verify changes work
$ git commit

# ❌ WRONG: Large config changes without testing
# Add 50 settings, rebuild, everything breaks

Why: Incremental testing isolates issues and saves debugging time.

9. Document Custom Keybindings

# ✅ CORRECT: Documented keybindings
{
  dconf.settings = {
    # Custom keybindings
    "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
      binding = "<Super>Return";
      command = "kitty";
      name = "Launch Terminal";
    };
    # Super+Return: Launch terminal
  };
}

# ❌ WRONG: Cryptic bindings
{
  dconf.settings."org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0".binding = "<Super>Return";
  # What does this do? No one knows!
}

Why: Documentation helps future you and collaborators.

10. Handle Multi-User Setups Properly

# ✅ CORRECT: Per-user configuration
{
  home-manager.users.alice = {
    dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
  };

  home-manager.users.bob = {
    dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-light";
  };
}

# ❌ WRONG: System-wide user settings
{
  programs.dconf.profiles.user.databases = [{
    settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
  }];
  # Applies to all users!
}

Why: Different users have different preferences.

Anti-Patterns: What to Avoid

1. ❌ Manual Extension Installation

# WRONG: Installing extensions manually
$ gnome-extensions install extension.zip

# CORRECT: Declarative installation
{
  home.packages = [ pkgs.gnomeExtensions.dash-to-dock ];
  dconf.settings."org/gnome/shell".enabled-extensions = [
    pkgs.gnomeExtensions.dash-to-dock.extensionUuid
  ];
}

Why: Manual installations are not reproducible and lost on rebuild.

2. ❌ Using gnome-tweaks for Settings

# WRONG: Configuring via gnome-tweaks
# Click, click, click...

# CORRECT: Declarative dconf settings
{
  dconf.settings."org/gnome/desktop/interface" = {
    clock-show-weekday = true;
    show-battery-percentage = true;
  };
}

Why: GUI changes are ephemeral; dconf settings are reproducible.

3. ❌ Ignoring Extension Dependencies

# WRONG: Missing dependencies
{
  dconf.settings."org/gnome/shell/extensions/user-theme".name = "MyTheme";
  # Extension not installed!
}

# CORRECT: Install extension first
{
  home.packages = [ pkgs.gnomeExtensions.user-themes ];
  dconf.settings."org/gnome/shell" = {
    enabled-extensions = [ pkgs.gnomeExtensions.user-themes.extensionUuid ];
  };
  dconf.settings."org/gnome/shell/extensions/user-theme".name = "Adwaita-dark";
}

Why: Extension settings are useless without the extension.

4. ❌ Hardcoding Paths

# WRONG: Hardcoded paths
{
  dconf.settings."org/gnome/desktop/background".picture-uri = "file:///home/user/wallpaper.png";
}

# CORRECT: Relative to config
{
  dconf.settings."org/gnome/desktop/background".picture-uri = "file://${./wallpaper.png}";
}

# BEST: Use Stylix
{
  stylix.image = ./wallpaper.png;
  stylix.targets.gnome.enable = true;
}

Why: Hardcoded paths break portability and reproducibility.

5. ❌ Mixed Imperative and Declarative

# WRONG: Some settings declarative, some manual
{
  dconf.settings."org/gnome/desktop/interface".color-scheme = "prefer-dark";
  # Then manually changing theme via gnome-tweaks
}

# CORRECT: Everything declarative
{
  dconf.settings = {
    "org/gnome/desktop/interface" = {
      color-scheme = "prefer-dark";
      gtk-theme = "Adwaita-dark";
      icon-theme = "Papirus-Dark";
    };
  };
}

Why: Mixed approaches lead to configuration drift.

6. ❌ Not Restarting GNOME Session

# WRONG: Expecting immediate changes
$ home-manager switch
# Settings don't apply!

# CORRECT: Log out and back in
$ home-manager switch
$ gnome-session-quit --logout

Why: Many GNOME settings require session restart to take effect.

7. ❌ Overusing environment.systemPackages

# WRONG: User applications in system packages
{
  environment.systemPackages = with pkgs; [
    firefox
    vscode
    spotify
  ];
}

# CORRECT: User packages in Home Manager
{
  home-manager.users.alice = {
    home.packages = with pkgs; [
      firefox
      vscode
      spotify
    ];
  };
}

Why: User applications belong in user profiles, not system-wide.

8. ❌ Ignoring GNOME Shell Version

# WRONG: Using extensions without checking compatibility
{
  home.packages = [ pkgs.gnomeExtensions.some-old-extension ];
  # May not work with current GNOME version!
}

# CORRECT: Check compatibility or pin GNOME version
{
  # Pin to GNOME 45
  services.xserver.desktopManager.gnome.enable = true;
  environment.systemPackages = with pkgs.gnome; [
    # Packages compatible with GNOME 45
  ];
}

Why: Extensions break between GNOME versions; version awareness prevents issues.

9. ❌ Forgetting to Disable User Extensions

# WRONG: Enabling extensions but leaving disable flag
{
  dconf.settings."org/gnome/shell".enabled-extensions = [ "..." ];
  # But disable-user-extensions defaults to true!
}

# CORRECT: Explicitly enable user extensions
{
  dconf.settings."org/gnome/shell" = {
    disable-user-extensions = false;
    enabled-extensions = [ "..." ];
  };
}

Why: Extensions won't load if user extensions are disabled.

10. ❌ Not Using dconf-editor for Discovery

# WRONG: Guessing setting paths
{
  dconf.settings."org/gnome/display/resolution" = "1920x1080";  # Doesn't exist
}

# CORRECT: Use dconf-editor or dconf watch
$ dconf watch /
# Make change in GUI
# See actual path: /org/gnome/desktop/interface/scaling-factor

Why: Wrong paths silently fail; discovery ensures correctness.

Troubleshooting and Debugging

Issue 1: Extensions Not Loading

Symptoms: Extensions installed but not visible in GNOME

Diagnosis:

# Check if extensions are installed
ls ~/.local/share/gnome-shell/extensions/

# Check enabled extensions
dconf read /org/gnome/shell/enabled-extensions

# Check if user extensions are disabled
dconf read /org/gnome/shell/disable-user-extensions

Fix:

{
  dconf.settings."org/gnome/shell" = {
    disable-user-extensions = false;  # Must be false!
    enabled-extensions = with pkgs.gnomeExtensions; [
      dash-to-dock.extensionUuid
    ];
  };
}

Issue 2: Settings Not Persisting

Symptoms: dconf settings revert after session restart

Diagnosis:

# Check Home Manager service status
systemctl status home-manager-$USER

# Check for conflicts
dconf dump / | grep -A 5 "setting-key"

Fix:

# Restart Home Manager service
systemctl restart home-manager-$USER

# Or rebuild
home-manager switch

Issue 3: Theme Not Applying

Symptoms: Stylix theme not visible in GNOME

Diagnosis:

# Check GTK theme
gsettings get org.gnome.desktop.interface gtk-theme

# Check if Stylix targets are enabled
nix eval .#nixosConfigurations.hostname.config.stylix.targets.gnome.enable

Fix:

{
  stylix = {
    enable = true;
    targets = {
      gnome.enable = true;  # Must be enabled
      gtk.enable = true;    # Must be enabled
    };
  };
}

Issue 4: Cursor Theme Issues

Symptoms: Cursor doesn't match theme or appears as default X cursor

Diagnosis:

# Check cursor theme
gsettings get org.gnome.desktop.interface cursor-theme

# Check if cursor package is installed
nix-store -q --references /run/current-system | grep cursor

Fix:

{
  stylix.cursor = {
    package = pkgs.bibata-cursors;
    name = "Bibata-Modern-Classic";
    size = 24;
  };

  # Or manually via dconf
  dconf.settings."org/gnome/desktop/interface" = {
    cursor-theme = "Bibata-Modern-Classic";
    cursor-size = 24;
  };
}

Alternative: Reset dconf completely

dconf reset -f /

Issue 5: GDM Not Showing Users

Symptoms: Login screen shows "Not listed?" instead of usernames

Diagnosis:

# Check if shell is registered
echo $SHELL

# Check NixOS shell configuration
cat /etc/shells

Fix:

{
  # Register user shell
  environment.shells = with pkgs; [ zsh bash ];

  users.users.alice = {
    shell = pkgs.zsh;
  };
}

Issue 6: Extension Configuration Not Working

Symptoms: Extension settings don't change behavior

Diagnosis:

# Find extension's schema
dconf dump /org/gnome/shell/extensions/

# Check if extension is actually enabled
gnome-extensions list --enabled

Fix:

{
  # Ensure extension is enabled BEFORE configuring
  dconf.settings = {
    "org/gnome/shell".enabled-extensions = [
      pkgs.gnomeExtensions.dash-to-dock.extensionUuid
    ];

    # Then configure
    "org/gnome/shell/extensions/dash-to-dock" = {
      dock-position = "BOTTOM";
    };
  };
}

Issue 7: Keybindings Not Working

Symptoms: Custom keybindings don't trigger

Diagnosis:

# Check keybinding configuration
dconf dump /org/gnome/settings-daemon/plugins/media-keys/

# Test if command works
kitty  # Or whatever command

Fix:

{
  dconf.settings = {
    # Must register custom keybinding path
    "org/gnome/settings-daemon/plugins/media-keys" = {
      custom-keybindings = [
        "/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
      ];
    };

    # Then define the keybinding
    "org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
      binding = "<Super>Return";
      command = "kitty";
      name = "Launch Terminal";
    };
  };
}

Issue 8: Fractional Scaling Blurry

Symptoms: UI elements blurry with fractional scaling

Diagnosis:

# Check current scaling
gsettings get org.gnome.desktop.interface scaling-factor

Fix:

{
  # Enable experimental features for better fractional scaling
  programs.dconf.profiles.user.databases = [{
    settings."org/gnome/mutter".experimental-features = [
      "scale-monitor-framebuffer"
    ];
  }];

  # Or use integer scaling
  dconf.settings."org/gnome/desktop/interface".text-scaling-factor = 1.25;
}

Issue 9: GNOME Console Theme Not Matching

Symptoms: GNOME Console (kgx) doesn't use Stylix theme

Diagnosis:

# Check if Stylix GNOME Console target exists
nix search nixpkgs gnome-console

Fix:

{
  # Use different terminal
  home.packages = [ pkgs.kitty ];  # Stylix supports kitty better

  # Or configure GNOME Console manually
  dconf.settings."org/gnome/Console" = {
    theme = "auto";  # Follows system theme
  };
}

Issue 10: Performance Issues

Symptoms: GNOME feels sluggish or laggy

Diagnosis:

# Check enabled extensions
gnome-extensions list --enabled

# Monitor resource usage
gnome-system-monitor

# Check for errors
journalctl -b | grep -i gnome

Fix:

{
  # Disable unnecessary extensions
  dconf.settings."org/gnome/shell".enabled-extensions = [
    # Only essential extensions
    pkgs.gnomeExtensions.appindicator.extensionUuid
  ];

  # Disable animations
  dconf.settings."org/gnome/desktop/interface".enable-animations = false;

  # Use lighter theme
  services.gnome.core-apps.enable = false;
}

Discovery Tools

dconf watch

Monitor dconf changes in real-time:

# Watch all changes
dconf watch /

# Make change in GNOME Settings
# Output shows the dconf path and value

dconf-editor

Visual dconf browser:

{
  environment.systemPackages = [ pkgs.dconf-editor ];
}

Launch and explore /org/gnome/ tree to find settings.

gsettings

Query schemas and values:

# List all schemas
gsettings list-schemas

# List keys in a schema
gsettings list-keys org.gnome.desktop.interface

# Get current value
gsettings get org.gnome.desktop.interface color-scheme

# Get possible values
gsettings range org.gnome.desktop.interface color-scheme

Extension UUID Discovery

# List installed extensions with UUIDs
gnome-extensions list

# Get UUID from package
nix eval --raw nixpkgs#gnomeExtensions.dash-to-dock.extensionUuid

Complete Configuration Template

# configuration.nix
{ config, pkgs, inputs, ... }:
{
  # Import Stylix
  imports = [
    inputs.stylix.nixosModules.stylix
  ];

  # GNOME Desktop
  services.displayManager.gdm.enable = true;
  services.desktopManager.gnome.enable = true;

  # Minimal GNOME
  services.gnome.core-apps.enable = false;
  environment.gnome.excludePackages = with pkgs; [
    gnome-tour
  ];

  # System packages
  environment.systemPackages = with pkgs; [
    gnome-tweaks
    dconf-editor
    gnome-extension-manager
  ];

  # Stylix theming
  stylix = {
    enable = true;
    base16Scheme = "${pkgs.base16-schemes}/share/themes/gruvbox-dark-medium.yaml";
    image = ./wallpaper.png;

    fonts = {
      monospace = {
        package = pkgs.nerdfonts.override { fonts = [ "JetBrainsMono" ]; };
        name = "JetBrainsMono Nerd Font Mono";
      };
      sansSerif = {
        package = pkgs.inter;
        name = "Inter";
      };
    };

    cursor = {
      package = pkgs.bibata-cursors;
      name = "Bibata-Modern-Classic";
      size = 24;
    };

    targets = {
      gnome.enable = true;
      gtk.enable = true;
    };
  };

  # Home Manager
  home-manager.users.myuser = { pkgs, config, lib, ... }: {
    # dconf settings
    dconf = {
      enable = true;
      settings = {
        # Interface
        "org/gnome/desktop/interface" = {
          color-scheme = "prefer-dark";
          enable-hot-corners = false;
          clock-show-weekday = true;
          show-battery-percentage = true;
        };

        # Window manager
        "org/gnome/desktop/wm/preferences" = {
          button-layout = "appmenu:minimize,maximize,close";
          num-workspaces = 4;
        };

        # Peripherals
        "org/gnome/desktop/peripherals/touchpad" = {
          tap-to-click = true;
          two-finger-scrolling-enabled = true;
        };

        # Extensions
        "org/gnome/shell" = {
          disable-user-extensions = false;
          enabled-extensions = with pkgs.gnomeExtensions; [
            dash-to-dock.extensionUuid
            appindicator.extensionUuid
          ];
          favorite-apps = [
            "org.gnome.Nautilus.desktop"
            "firefox.desktop"
          ];
        };

        # Extension settings
        "org/gnome/shell/extensions/dash-to-dock" = {
          dock-position = "BOTTOM";
          dash-max-icon-size = 48;
        };
      };
    };

    # Packages
    home.packages = with pkgs; [
      # Extensions
      gnomeExtensions.dash-to-dock
      gnomeExtensions.appindicator

      # Icons
      papirus-icon-theme
    ];
  };
}

Resources

Official Documentation

Community Resources

Tools

  • dconf-editor: Browse and edit dconf settings
  • gnome-tweaks: Additional GNOME customization
  • gnome-extension-manager: Manage extensions (use declaratively!)

Summary

This GNOME skill provides:

  • ✅ Complete installation and configuration guide
  • ✅ Deep Stylix integration for consistent theming
  • ✅ Extension management best practices
  • ✅ Golden path for correct configuration
  • ✅ Anti-patterns to avoid common mistakes
  • ✅ Comprehensive troubleshooting guide
  • ✅ Discovery tools and debugging techniques
  • ✅ Real-world configuration examples

Key Takeaways:

  1. Use Home Manager for user settings, NixOS for system settings
  2. Stylix provides centralized, consistent theming
  3. Extensions must be enabled via dconf
  4. Use dconf watch / to discover settings
  5. Organize configuration logically
  6. Test incrementally
  7. Avoid imperative configuration
  8. Session restart often required for changes

Configure GNOME declaratively with NixOS for a reproducible, version-controlled desktop experience! 🚀

Skills Info
Original Name:gnomeAuthor:olafkfreund