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:
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
:
mkdir ~/nix-homecd ~/nix-homecode 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:
{ 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:
{ 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
:
# ... start of flakeconfig = { 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:
which git/usr/bin/git
Rebuild your HOME
:
cd ~/nix-homenix 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:
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:
cd ~/nix-homegit init --initial-branch=maingit remote add origin <the-link-you-just-copied>git add flake.nixgit 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
:
- Find the files:
Terminal window $ cd ~$ ls -a.bash_profile .bashrc - Copy them over:
Terminal window $ cp .bash_profile .bashrc ~/nix-home/ - Add them to
home.file
:flake.nix # ... start of flakeconfig = {home.username = "beat";home.homeDirectory = "/home/beat";home.packages = [pkgs.gitpkgs.wget];home.file = {".bash_profile".source = ./.bash_profile;".bashrc".source = ./.bashrc;};# DO NOT CHANGE THESE LINESprograms.home-manager.enable = true;home.stateVersion = "25.05";};# ... closing braces - 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
:
- 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) - Copy the file over to
~/nix-home/<the-file-path>
- Add the file to
home.file
- Rebuild you
HOME