using GNOME & Pantheon together in NixOS

I am not an expert on this topic; this is just a post from a new Nix user about how I solved this issue.

After installing NixOS, i wanted to explore different desktop environments and window managers as i had heard how easy it was to switch between different setups reliably but i still wanted to keep GNOME as my main setup in NixOS. However when I tried to install Pantheon alongside GNOME, i ran into a problem. Due to overlapping components between the two DEs Nix did not build the system.

I believe problems like these exist with other DEs as well. When i ran into this issue, unfortunately there simply was no quick tutorial or explanation available online to fix these conflicts, aside from a few GitHub issues, like this one.

the problem

Well, the primary problem is things between the two desktop environments conflict. We can solve those with nix specialisations. But, more importantly the secondary issue is that both desktop environments always set few configs that makes sense and fits well in one desktop but when logged into another desktop environment then it clashes and you will have a inconsistent system. An example of it is the GTK theme or cursor theme set by both desktops.

To solve that i used impermanence. Basically since NixOS can be rebuilt with just /nix directory, we can destory / and rebuild the system on every boot and on doing so when i boot into GNOME the things required by GNOME are placed when booting into Pantheon the things required by Pantheon are placed in the system.

Note: You can still persist directories and files you want to keep between reboots.

the solution

To turn your NixOS to follow impermanence you need to first make few changes to your drives. There are lots of ways to configure your system including but not not limited to different filesystems, encryption or no encryption.

I went with tmpfs as the filesystem for my root. For this, i had to make changes to my hardware-configuration.nix. The following are the changes i made to turn my NixOS into a impermanance system. If you too want to do so, follow these amazing tutorials and resources.

on flake.nix.

{
  description = "System configuration";
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
+   impermanence.url = "github:nix-community/impermanence";
  };

+ outputs = inputs@{ nixpkgs, impermanence, ... }: {
    nixosConfigurations = {
      yourUsername = nixpkgs.lib.nixosSystem {
        system = "x86_64-linux";
        modules = [
          ./system/system.nix
          impermanence.nixosModules.impermanence
        ];
      };
    };
  };
}

on persistance.nix called by system.nix

{ lib, config, pkgs, ... }:
{
  environment.persistence."/nix/persist" = {
    hideMounts = true;
    directories = [
      "/var/log"
      "/var/lib/systemd/coredump"
      "/var/lib/nixos"
      "/etc/NetworkManager/system-connections"
    ];
    files = [
      # machine-id is used by systemd for the journal, if you don't persist this
      # file you won't be able to easily use journalctl to look at journals for
      # previous boots.
      "/etc/machine-id"
    ];
    users.crimson = {
      directories = [
        ".local/share/Trash"
        "Downloads"
        "Documents"
        "Pictures"
        "Music"
        "Videos"
        "Templates"
        # do not forget to add your `.nix` config / dotfiles path
      ];
      files = [
        ".zsh_history"
      ];
    };
  };
}

on hardware-configuration.nix

+ fileSystems."/" = {
+   device = "none";
+   fsType = "tmpfs";
+   options = [ "defaults" "size=25%" "mode=755" ];
+ };

+ fileSystems."/nix" = {
+   device = "/dev/disk/by-uuid/6f016b80-289c-4fa9-b5f9-162fab437051";
+   fsType = "ext4";
+ };

+ fileSystems."/etc/nixos" = {
+   device = "/nix/persist/etc/nixos";
+   fsType = "none";
+   options = [ "bind" ];
+ };

+ fileSystems."/var/log" = {
+   device = "/nix/persist/var/log";
+   fsType = "none";
+   options = [ "bind" ];
+ };

Now with these changes, the configurations will not persist when restarting. As such, its now finally possible to install two systems at once. For this, i made use of nix specialisation. It essentially makes a twin generation of your OS but with the changes you have specified.

I did the following.

on eos.nix that is called by system.nix

{ lib, config, pkgs, ... }:
{
  specialisation.eos.configuration = {
    services.xserver = {
      displayManager = {
        gdm.enable = lib.mkForce false;
        lightdm.enable = true;
      };
      desktopManager = {
        gnome.enable = lib.mkForce false;
        pantheon = {
          enable = true;
          extraWingpanelIndicators = with pkgs; [ wingpanel-indicator-ayatana ];
          extraSwitchboardPlugs = [ ];
        };
      };
    };
  };
}

eos is the name i gave to this specialisation. The above snippet basically overrides GDM with lightdm by disabling GDM and enabling lightdm. GNOME is also disabled and pantheon is enabled.

With the above changes, rebuilding the system will make two different systems within one generation (within as in, two systems are still made from one config at once). On reboot the systemd boot menu will ask you which system to boot into.

People on Nix/NixOS (unofficial) discord helped me with this, If you have any issues you should join it and freely ask questions.

p.s. my full config is available on GitHub. the readme in there has a good enough guide to basically replicate my system. It’s meant to be used only by me, but you can use it as reference.