Skip to content

Chapter 3 - Home Manager

Home Manager (often abbrevieted to HM) is a project similar to NixOS, but for a specific user’s home folder. You use NixOS to manage system programs, configuration, etc. But Home Manager is programs and configuration for a specific user.

In this chapter we will…

  1. Add Home Manager as an input to our flake
  2. Learn how to add home manager modules
  3. Configure our .face file with home manager as an example

Adding Home Manager as an Input

First we need to add Home Manager as an input to our flake.

  1. In flake.nix, add a new attr set to the inputs attr set called home-manager (this can technically be called whatever you like, some people shorten this to hm).
    flake.nix
    inputs = {
    nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
    home-manager = {
    url = "github:nix-community/home-manager";
    inputs.nixpkgs.follows = "nixpkgs";
    };
    };
    This tells Nix two things:
    1. We have an input named home-manager that should be fetched from the nix-community/home-manager GitHub repo.
    2. The Home Manager flake itself depends on nixpkgs as an input. To keep thing consistent, we tell Nix that input should follow our nixpkgs input.
  2. Now, we add home-manager as an argument to our outputs function.
    flake.nix
    outputs = inputs @ {
    self,
    nixpkgs,
    home-manager,
    } let ... in {
    # ...
    }

We now have access to home manager in our flake!

Telling NixOS About Home Manager

Now we need NixOS to access home manager. In our modules list we’ll add home-manager.nixosModules.home-manager.

flake.nix
modules = [
./modules/config.nix
home-manager.nixosModules.home-manager
];

This will load additional options into NixOS to let us use home manager.

Configuring Home Manager

Now we’re ready to start using Home Manager within our NixOS config.

In config.nix (or a separate module if you feel like it). Create a new attr set called home-manager.

We’re going to fill this with our home config, replace YOURUSER with your username below.

config.nix
home-manager = {
useGlobalPkgs = true; # Sets HM to use the global nixpkgs instance
useUserPackages = true;
extraSpecialArgs = { inherit inputs; }; # Pass inputs to HM modules too
users.YOURUSER = import ../home/home.nix; # Point HM to our root home manager module for user "YOURNAME"
};

Here you can see we’re importing another file (../home/home.nix). This file will hold a home manager module, these are very similar in appearance to NixOS modules so I recommend placing them in a different folder from modules to differentiate them.

Create home/home.nix and fill it with boilerplate for now.

  • flake.nix
  • flake.lock
  • Directorymodules/
    • config.nix
  • Directoryhome/
    • home.nix Root HM Module
home/home.nix
{pkgs, ...}: {
}

Using Home Manager

First things first we’ll add these options, replace YOURNAME with your username.

home/home.nix
{pkgs, ...}: {
home = {
username = "YOURUSER";
homeDirectory = "/home/YOURUSER";
stateVersion = "24.11";
};
}

This will tell home manager your username and where your home folder is.

Example: Adding .face

To go into a quick use case for HM, we’ll add a file to the root of our home folder, .face.

This file is used by some programs to know what profile picture to display on various UI components.

  1. Place the image file in your config’s repo (I like to place any non-nix files in a folder called res, for resources).

    • flake.nix
    • flake.lock
    • Directorymodules/
    • Directoryhome/
    • Directoryres/
      • YOURIMAGE.png
  2. Can’t forget to git add of course.

    Terminal window
    git add .
  3. In an HM module set up a link, replace YOURIMAGE.png with the name of your image file.

    home/home.nix
    {pkgs, ...}: {
    # ...
    home.file.".face".source = ../res/YOURIMAGE.png;
    }

Run the VM again and check your home folder, you’ll notice a .face symlink!

  • Directory/home/user
    • .face A symlink to the nix store!