Am i following the workflow correctly?

I initially added some basic software’s into /etc/configuration.nix file (vlc, libreOffice, tmux, emacs, vim etc)

later, installed home-manager and then flakes.

created .dotfiles directory under my home path and created link to /etc/configurations.nix and hardware-configuration.nix file over here.

created home.nix and flake.nix

now, if i wanted to install anything system wide, im still using the configurations.nix.
i haven’t used the home.nix yet since im not confident enough.

my current workflow and its commands:

currently after making any changes(any new software being added) inside the configurations.nix,

sudo nixos-rebuild switch --flake .

if changes made on home.nix

home-manager switch --flake .

to list generations

sudo nix-env --list-generations --profile /nix/var/nix/profiles/system

to delete older generations

sudo nix-collect-garbage -d


nix-collect-garbage --delete-old

(but this doesn’t deletes the old generations from my boot menu)
so i usually reboot to see if the changes are in effect. else i use the below command.

sudo /run/current-system/bin/switch-to-configuration boot

im still not having a clear understanding on the generation deletion still. so correct me please.

My Understanding:

please correct me if im wrong

home-manager takes control of all of the dotfiles and user level files, ignores the system level files. And takes care of things like package versions, dependencies, linking (in the store), while switching to new changes on any of the files that home-manager monitors, and if want to replicate this setup across different machines.

configuration.nix will take care of the system wide settings and software installations. which can be said as, to the current machine alone.

flake, i still cant get a clear picture on it. but still here i go,. something like gits version history for the os configurations and home.nix etc


  1. whats the difference between nix-env --list-generations and sudo nix-env --list-generations --profile /nix/var/nix/profiles/system

  2. for my understanding can i consider home.nix file as something like an equivalent to portable version of configuration.nix

    • currently i have installed packaged through configuration.nix and my home.nix is still pretty fresh and untouched. whats the best way to move packages from configuration.nix to home.nix. can i just move the list from configuration.nix environment.systemPackages = with pkgs; [ ] to home.nix home.packages = [ ] ? and if i do it so, what should be the sequence of command that i should follow
    • Once having a home.nix, is it advisable to touch configuration.nix file. if so under which circumstances can the configuration.nix be used/touched and what should be the commands being followed.
      • say if configuration.nix is touched and i havent made any changes to home.nix what sequence of commands should i follow.
      • say if i have made change to home.nix and configuration.nix on the same go, what sequence of command should i follow.
      • and finally, if i touch only the home.nix file the command i should use is home-manager switch --flake ., correct ?
      • Reason im asking the above 3 scenarios is, without better understanding i have given sudo nixos-rebuild switch --flake . and home-manager switch --flake . distinctively and also one after the other(sometime first nixos-rebuild and then homemanager switch. sometimes the other way) at times in the past. because of which i have seen some weird effect like, some software being not available though they are present in the package list(still inside configuration.nix).
      • in short, if i make changes on either one or both (configuration.nix or home.nix) what sequence of command should i follow.
  3. after removing the older generations, if i want to reflect the same on the boot menu after couple of days of testing the new generations, is the command being issued above correct ? if there is a proper way to do it please correct me. (don’t want cli helper until i get a clear understanding on the old generations deletion.

  4. when should i use nix flake update

  5. Please correct my understanding of workflow or if there is a better workflow. i dont want to use any cli helper before i have complete understanding of the nixos philosophy

Hey there,

you don’t have to follow a strict protocol, just use those parts of the Nix ecosystem that you feel you need. For example, if you’re like me, you might realize - after some experimentation - that you don’t need/want Home Manager (yet) and just remove it from your configuration. That’s totally fine.

Now concerning some of your questions:


Garbage collection doesn’t remove the entries in your boot menu. Instead, they are updated when you rebuild your system with e.g. sudo nixos-rebuild switch. So, after garbage collection you need to run this command to get rid of the old boot entries.


Everytime you install a package imperatively (which should be avoided usually) by doing for example

nix-env -iA nixos.asciiquarium

a new user profile generation is created. According to the Nix Reference Manual,

nix-env --list-generations

prints a list of all the currently existing generations for the active (user) profile.

More generally, the description of nix-env reads: “The command nix-env is used to manipulate Nix user environments. User environments are sets of software packages available to a user at some point in time. In other words, they are a synthesised view of the programs available in the Nix store. There may be many user environments: different users can have different environments, and individual users can switch between different environments.”
(FYI, with Flakes enabled, you can also use nix profile install instead of nix-env -iA .)
Since you’re using Home Manager for installing software on a user-level you probably don’t need/want this.

On the other hand,

sudo nix-env --list-generations --profile /nix/var/nix/profiles/system

lists your available system generations (the ones that appear in your boot menu). You can also check these with

ls -la /nix/var/nix/profiles/


nix flake update

just updates the flake.lock file, effectively controlling which version of any given package gets installed. nix flake update --help states: “This command recreates the lock file of a flake (flake.lock), thus updating the lock for every unlocked input (like nixpkgs) to its current version.”

You need to do this before you manually update your system with

sudo nixos-rebuild boot --flake .#hostname

Instead, you could set up automatic updates in your configuration which can also take care of this. Like so:

system.autoUpgrade = {
  enable = true;
  operation = "boot"; # auto updates apply on reboot
  flake = "/<path>/<to>/flake.nix";
  flags = [
    "-L" # print build logs
  allowReboot = false;
  dates = "17:00";
  randomizedDelaySec = "30min";

For further documentation regarding auto updates see also the NixOS Manual, the unofficial Wiki, or the unofficial NixOS & Flakes Book .

Thanks a lot for your detailed explanations, views and suggestions @sleepy. And please forgive me for late reply.

understood, But since i wanted to migrate all my machines to nix i wanted to make use of home-manager. So if i want to remove home-manager now, just deleting the home.nix file and doing a rebuild switch be sufficient ?

when you mean “imperatively”, is it installing packages not permanently(i mean not through configuration.nix or home.nix) ?

so in short, one is user level generation and the other is system level generation.:+1: Understood

wow, that is a :relieved: relief. Thanks for the extra information.

usually When i add some package, i leave one old generation for a week or so and then i try to do a garbage collect at first and then do a switch rebuild. Even then i use to see older generations on my boot menu. but every where i see on internet, its same as how you have said. after some tries i found

sudo /run/current-system/bin/switch-to-configuration boot

removed my older generation. I wanted to know why does only switch rebuild after garbage collection works for others as you have mentioned and not for me. And now, its even worst.

If possible you can take a look at my current problem, where the default generation is older one and i have a newer generation ahead of the my current defaultas per boot, but when enter into default(old) and try to list the generation, it says im under new generation. This confusing situation made me realized that this conflict is due to the mishandling of commands(home-manager & system configuration) which i tried out unknowingly. I wanted to know what caused this exactly, which was the main reason why i wrote this topic. since then i stopped adding any changes to my system and wanted to fix it before i go further.

Removing Home Manager

You can remove Home Manager by deleting or commenting out (by enclosing with /* and */ ) the relevant parts in your flake.nix: your inputs would then look something like this

inputs = {
  nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
  /* home-manager = {
    url = "github:nix-community/home-manager/release-23.11";
    inputs.nixpkgs.follows = "nixpkgs";
  }; */

and if you used Home Manager as a NixoS module (instead of standalone), then in the nixosConfigurations section you comment out (or delete) the home-manager module:

nixosConfigurations = {
  "<hostname>" = nixpkgs.lib.nixosSystem {
    inherit system;
    specialArgs = { };
    modules = [
      /* home-manager.nixosModules.home-manager {
        home-manager = {
          useGlobalPkgs = true;
          useUserPackages = true;
          users.<username> = import ./<path>/<to>/home.nix;
          extraSpecialArgs = { };
      } */

After that, do a nix flake update followed by nixos-rebuild boot to apply the changes.

Imperatively installing packages and profiles as gcroots

There are actually two answers to this question:

  1. Yes, “declarative” means you “describe” how you want your whole system to be (e.g. in configuration.nix), including all the desired software, and Nix realizes/creates that system, whereas “imperative” means you instruct the system to do a specific task (like installing a specific package or executing a certain command). If, later, you want to do the same task again, you will have to remember the exact sequence of commands. That’s where the advantage of the declarative approach lies: it enables reproducibility because you can copy and transfer your declaration as is. Of course, imperatively installed software won’t be transferred this way. That’s why, in a sense, it is “not permanent”.
  2. No, packages that you install with nix profile install or nix-env -iA are permanently available on your system, because they are part of a user profile. That means, they won’t be garbage-collected until you delete them from your profile. Such profiles act as GC roots: put simply, everything in the Nix store which is referenced by a link from outside the store is protected from being garbage-collected. And everytime you install or remove a package this way, a new generation of that profile is generated. You can see your profiles in ~/.local/state/nix/profiles.

If you’re interested in how profiles, the Nix store and the linking system actually works, I highly recommend watching part of the video “Everyday Use of GNU Guix” (minutes 23 to 37) by Chris Marusich on YouTube. Nix works similar to Guix in this regard. (But the given commands differ.)

Old generations

That is weird. I currently don’t have any idea why that might be the case. But somewhat related, I’ve noticed in the screenshots you provided in your linked post that your system flake is still configured to use the old 23.05 stable branch. The stable releases usually receive bugfixes and security updates for seven months, so 23.05 is deprecated now. You probably want to change your configuration to 23.11. Maybe this in conjunction with the removal of Home Manager might eventually fix the issue with the generations as well?