< B / >

Setting Up Home Manager

So, you want to have a ~ where works on my system is a thing of the past?

You’ve come to the right place.

In this tutorial, I’m gonna show you how to set up your HOME with Home Manager using Nix Flakes on Linux.

First things first: Take one minute and look at the docs. They’re not a tutorial, but a good reference, and it’s definitely useful to have seen them once.

§ Chapter 1: A Basic Flake

With that out of the way—you first need to make sure you have Nix installed:

Terminal window
curl -fsSL https://install.determinate.systems/nix | sh -s -- install

Then, you need a place to store your Home Manager configuration. Create a folder for it (name doesn’t matter) and a flake.nix inside (name does matter). Then, let’s start writing your configuration inside the flake.nix:

Terminal window
mkdir ~/nix-home
cd ~/nix-home
code flake.nix # or whatever editor you prefer

The first thing our Home Manager Flake needs is a input to get packages from. We’re probably going to use some packages, so we need `nixpkgs`, and then we’re going to use home-manager, too:

flake.nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; # nixpkgs input
home-manager.url {
url = "github:nix-community/home-manager"; # home manager input
inputs.nixpkgs.follows = "nixpkgs"; # that takes the versions from our nixpkgs checkout
};
};
}

Then, we need to specify how to build the home configuration—we do that inside an output. For it to work, you need to know your username (in case you don’t know it, do a whoami in the shell).

So for me, beat, this would look like this:

flake.nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; # nixpkgs input
home-manager.url {
url = "github:nix-community/home-manager"; # home manager input
inputs.nixpkgs.follows = "nixpkgs"; # that takes the versions from our nixpkgs checkout
};
};
outputs = { nixpkgs, home-manager, ... }: # nix function syntax
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in
{
homeConfigurations."beat" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
config = {
home.username = "beat";
home.homeDirectory = "/home/beat";
# DO NOT CHANGE THESE LINES
programs.home-manager.enable = true;
home.stateVersion = "25.05";
};
];
};
};
}

Now’s finally the time to actually add things to your config. You can find all of the Home Manager Configuration Options here: https://nix-community.github.io/home-manager/options.xhtml

This is a website you’re probably gonna visit a lot over the course of the next few months.

But enough of that—time to add some packages. We can take whatever there is in nixpkgs. Let’s add git and wget:

flake.nix
# ... start of flake
config = {
home.username = "beat";
home.homeDirectory = "/home/beat";
home.packages = [
pkgs.git
pkgs.wget
];
# DO NOT CHANGE THESE LINES
programs.home-manager.enable = true;
home.stateVersion = "25.05";
};
# ... closing braces

And with that, time for our first rebuild. Let’s test that everything worked by checking where the git executable comes from. So, run this first:

Terminal window
which git
/usr/bin/git

Rebuild your HOME:

Terminal window
cd ~/nix-home
nix run home-manager/master -- switch --flake .

After it’s done, close and reopent the terminal once. Then, do which git again—it should say something like this:

Terminal window
which git
~/.nix-profile/bin/git

Now you know how to add packages declaratively and reproducibly to your HOME. Yay!

§ Intermezzo: Version Control

Before we go any further, it’s time give us some more safety trying things out. For that, we put our ~/nix-home under Version Control.

Make sure you have git set up.

Create a repository called ~/nix-home.

Copy the SSH link from here.

It should look like this: [email protected]:<username>/nix-home.git

Then, go back to your shell and do the following:

Terminal window
cd ~/nix-home
git init --initial-branch=main
git remote add origin <the-link-you-just-copied>
git add flake.nix
git commit --message "Initial commit with wget and git"
git push --set-upstream origin main

But since this is not a git tutorial, let’s move on.

(The git flight rules are pretty decent.)

§ Chapter 2: Transferring your HOME

So far, the benefits of using home manager have been pretty much limited. I’ve promised no more Works on my Machine issues, remember?

To do that, it’s time to pull in your whole HOME config into your flake.

Let’s do it for the bash files, .bash_profile and .bashrc:

  1. Find the files:
    Terminal window
    $ cd ~
    $ ls -a
    .bash_profile .bashrc
  2. Copy them over:
    Terminal window
    $ cp .bash_profile .bashrc ~/nix-home/
  3. Add them to home.file:
    flake.nix
    # ... start of flake
    config = {
    home.username = "beat";
    home.homeDirectory = "/home/beat";
    home.packages = [
    pkgs.git
    pkgs.wget
    ];
    home.file = {
    ".bash_profile".source = ./.bash_profile;
    ".bashrc".source = ./.bashrc;
    };
    # DO NOT CHANGE THESE LINES
    programs.home-manager.enable = true;
    home.stateVersion = "25.05";
    };
    # ... closing braces
  4. And rebuild your HOME while backing up the old files:
    Terminal window
    home-manager switch --flake ~/nix-home -b backup

This general workflow works for every file in your HOME:

  1. Take any file in your HOME that looks like it might serve a purpose (possibly everything in .config, .bash_profile, .bashrc, .vimrc and basically any other dotfile)
  2. Copy the file over to ~/nix-home/<the-file-path>
  3. Add the file to home.file
  4. Rebuild you HOME