My NixOS Journey - Home Manager

In the last post I talked about installing NixOS and how you can find the packages and settings to be used on /etc/nixos/configurations.nix. If you care about setting up user profile declaratively, you will find home manager very quickly. Home manager can be used to not only install user specific packages but also manage application configurations. Some of them are not configurable via nixos options. (dconf.settings is a good example).

You can find home manager official doc here.

In today’s post, I will show you how to start using home manager. Let’s get started.

Installation

On NixOS you have two choices to install Home manager, either as NixOS module or in standalone mode. From my understanding, here are the pros/cons to use home manager as nixos module.

Pros:

  • You can easily backup, rollback and set up the entire system with a single nixos command.

Cons:

  • Making changes to home manager settings results in a whole system level rebuild, users end up having too many generations.

Install as Nix Module

If you want to install home manager as standalone mode, you can go here.

I will follow what is on the official documentation first and then show you how to optimize your config.

Add home manager channel

Let’s run below command to add 22.11 channel first.

1
2
sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-22.11.tar.gz home-manager
sudo nix-channel --update

Add hm to config

Next we need to add home manager to /etc/nixos/configuration.nix. Let’s open this file in text editor and

  • Add <home-manager/nixos> under imports
  • Set users.users.<name>.isNormalUser = true; (in my case this is already true)
  • Add home-manager.users.<name> = { pkgs, ... }: { related config as below
1
2
3
4
5
...
home-manager.users.<name> = { pkgs, ... }: {
home.packages = [ pkgs.atool pkgs.httpie ];
home.stateVersion = "22.11";
};

Let’s rebuild and the command should work this time. We can use http to verify httpie is installed.

1
2
[fomm@nixos:~]$ http --version
3.2.1

Above example is pretty self-explanatory. It use home-manager for user.<name> and installs atool and httpie for this user.

If we take a look at where http is installed, we should see it is installed under my user’s home directory.

1
2
[fomm@nixos:~]$ which http
/home/fomm/.nix-profile/bin/http

As home manager configs are for a specific user, let’s split its configs from the main system configuration.

Separate configs

On the official documentation it mentioned there should be a home.nix but we don’t have this file when we install home manager as NixOS module. Let’s manually create home.nix with below config in /etc/nixos/ folder.

1
2
3
4
5
6
7
{ config, pkgs, ... }:

{
home.username = "<username>";
home.homeDirectory = "/home/<username>";
home.stateVersion = "22.11";
}

Then we need to change home-manager part on /etc/nixos/configuration.nix to below. I also enable useGlobalPkgs and useUserPackages here. Please have a read if you want to know what these two variables do.

1
2
3
4
5
6
...
home-manager = {
useGlobalPkgs = true;
useUserPackages = true;
users.<name> = import ./home.nix;
};

Let’s run sudo nixos-rebuild switch to rebuild. Because we removed home.packages = [ pkgs.atool pkgs.httpie ]; with above changes, atool and httpie will also be removed. We can verify this as below.

1
2
[fomm@nixos:~]$ which http
which: no http in (/run/wrappers/bin:/home/fomm/.nix-profile/bin:/etc/profiles/per-user/fomm/bin:/nix/var/nix/profiles/default/bin:/run/current-system/sw/bin)

Let’s move on to the next section to learn how to use home manager.

Install in standalone mode

Running home manager in standalone mode means you will use home-manager command to mange home manager related configs.

Add home manager channel

Let’s run below command to add 22.11 channel first.

1
2
sudo nix-channel --add https://github.com/nix-community/home-manager/archive/release-22.11.tar.gz home-manager
sudo nix-channel --update

Install Home manager

To install, we just need to run below command.

1
nix-shell '<home-manager>' -A install

Use home manager

Config folders (where we can find home.nix):

  • NixOS module: /etc/nixos
  • Standalone: ~/.config/nixpkgs/

Update nix channel:

  • NixOS: sudo nix-channel --update
  • Home manager: nix-channel --update

Apply home manager changes command:

  • NixOS module: sudo nixos-rebuild switch
  • Standalone: home-manager switch

Install Nix Packages

We can install nix package by putting the package name under home.packages on home.nix. Let’s open this file and add below, this will install htop.

1
2
3
4
...
home.packages = with pkgs; [
htop
];

Once it we rebuild, we should have htop.

1
2
[fomm@nixos:~]$ htop --version
htop 3.2.1

Home manager configs

Now that we know how to install packages, let’s explore how to use Home manager to manage application configurations .

Let’s add below to home.nix and then run switch command to install.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
programs.zsh = {
enable = true;
enableCompletion = true;
enableAutosuggestions = true;
enableSyntaxHighlighting = true;
oh-my-zsh = {
enable = true;
plugins = [ "docker-compose" "docker" ];
theme = "dst";
};
initExtra = ''
bindkey '^f' autosuggest-accept
'';
};

programs.fzf = {
enable = true;
enableZshIntegration = true;
};

This is pretty self-explanatory.

  1. Install zsh, fzf.
  2. Enable syntax highlighting, completion and auto suggestion.
  3. Install oh-my-zsh, use dst theme and docker-compose, docker plugin.
  4. Ctrl + f to accept autosuggestion.

To find more home manager configs, the first place we can check is the manual page. We may also find some useful information from NixOS Wiki.

Now that zsh is installed, we can run zsh and we should see all the config above are working. We might also want to set zsh as our default shell. From NixOS Wiki page, we know w need to add below to /etc/nixos/configuration.nix.

1
2
users.users.<name>.shell = pkgs.zsh;
environment.shells = with pkgs; [ zsh ];

Let’s add these config and run sudo nixos-rebuild switch. The next time we log in to our terminal, we should see zsh is used.

Split HM configs

As you can imagine, the more home manager configs we need to use, the longer home.nix will be which makes managing this file very difficult in the future. What we can do is to split home.nix and put programs configs to different files and then import it back to home.nix.

Let’s create /apps folder in our config folder. Then we can create a zsh.nix file and put below content on it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
programs.zsh = {
enable = true;
enableCompletion = true;
enableAutosuggestions = true;
enableSyntaxHighlighting = true;
oh-my-zsh = {
enable = true;
plugins = [ "docker-compose" "docker" ];
theme = "dst";
};
initExtra = ''
bindkey '^f' autosuggest-accept
'';
};

programs.fzf = {
enable = true;
enableZshIntegration = true;
};
}

Next let’s go back to home.nix file and remove the programs.zsh section and import zsh.nix back.

1
2
3
4
5
6
{ config, pkgs, ... }:

{
imports = [
./apps/zsh.nix
];

Let’s rebuild again and we should see zsh is still running fine.

Let’s do one more thing by removing micro editor from system package and use home manager to manage it.

  1. Let’s comment out micro under environment.systemPackages on /etc/nixos/configuration.nix.

  2. Then we can create a micro.nix file under home manager /apps folder with below content.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    programs.micro = {
    enable = true;
    settings = {
    colorscheme = "material-tc";
    mkparents = true;
    softwrap = true;
    tabmovement = true;
    tabsize = 2;
    tabstospaces = true;
    autosu = true;
    };
    };
    }
  3. Then we can can add ./apps/micro.nix to home.nix and rebuild. We will get below error message. This is because we have ~/.config/micro/settings.json from previous installation, home manager wantss you to confirm if you need to backup.

    1
    2
    Existing file '/home/fomm/.config/micro/settings.json' is in the way of '/nix/store/78gyysv4v3wdkds5l50nv2vbiqj2avnk-home-manager-files/.config/micro/settings.json'
    Please move the above files and try again or use 'home-manager switch -b backup' to back up existing files automatically.
  4. Since I will use home manager to manage configs for micro, I delete the file and rebuild again. Rebuild should be successful this time. If we use micro again, we can see the indentation, colour theme are working exactly as our configs above.

That’s all I want to share with you today. I hope you can start building your nix configuration using home manager.

See you next time.