Setting up your dotfiles with home-manager as a flake

Home Manager is a great project to make managing your dotfiles via Nix super nice and easy. However, there is not a ton of documentation out there explaining how to use home-manager in a standalone way with flakes. I assume most people using flakes and home-manager simply use NixOS; although using home-manager standalone there is a good idea because you do not need to rebuild your whole system to change your Vim or shell config.

I found it a little difficult to figure out so here are some notes/snippets that hopefully helps others. I hope to come back to this post over time and make it a little easier to read, but hopefully official docs and etc simply get better to make it not needed.

To start, I followed the instructions here: Declarative management of dotfiles with Nix and Home Manager

But, they seem to be out of date or something because it didn’t work for me.

  1. The command to get things built and running is different and you need to pass --flake . in the flake directory
  2. You need to remember/know to restart your shell
  3. The way to specify where ./home.nix and how to write home.nix has changed.

Errors you may see:

  • “NIX_PATH unset” : This is because you’re using the wrong command and do not have channels setup. Using the right command will fix this without using channels
  • “home.nix no configuration found” : This is likely related to using the wrong command and not telling it to use your flake

Creating basic home-manager flake configuration

  1. Setup your ~/.config/nix/nix.conf to allow flakes

    # ~/.config/nix/nix.conf
    experimental-features = nix-command flakes 
    
  2. git init and nix flake init in your dotfiles repo

  3. Setup your basic flake.nix like this:

{
    description = "My Home Manager Flake";

    inputs = {
        nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
        home-manager = {
            url = "github:nix-community/home-manager";
            inputs.nixpkgs.follows = "nixpkgs";
        }
    };

    outputs = {nixpkgs, home-manager, ...}: {
        defaultPackage.x86_64-linux = home-manager.defaultPackage.x86_64-linux;
        defaultPackage.x86_64-darwin = home-manager.defaultPackage.x86_64-darwin;

        homeConfigurations = {
            "your.username" = home-manager.lib.homeManagerConfiguration {
                # Note: I am sure this could be done better with flake-utils or something
                pkgs = nixpkgs.legacyPackages.x86_64-darwin;

                modules = [ ./home.nix ];
            };
        };
    };
}

Some notes:

  • Other posts on setting up home-manager with flakes will tell you to put more options in homeConfigurtions."your.username", but that was the old way of doing things and just these options are needed.
  • On Apple M1/M2 systems it has often been recommended to use x86_64, but you can install it natively using aarch64.
    • An aside: You can use flake-utils to manage which systems are supported and etc.
    • It is possible to configure an x86_64 nixpkgs to allow to access x86_64 packages to use with rosetta when/where needed.

Your home.nix should look like this

{pkgs, ...}: {
    home.username = "your.username";
    home.homeDirectory = "/home/your.username";
    home.stateVersion = "22.11"; # To figure this out you can comment out the line and see what version it expected.
    programs.home-manager.enable = true;
}
  1. Run nix run . switch -- --flake . to build and setup home-manager. **Restart your shell or run exec $SHELL -l.

    nix run . switch is short for home-manager switch later. -- helps it understand which flags are for nix run vs to pass into home-manager switch.

  2. Modify home.packages in home.nix to add new packages to your environment.

{pkgs, ...}: {
    home.username = "your.username";
    home.homeDirectory = "/home/your.username";
    home.packages = [
        pkgs.nixfmt
        pkgs.cowsay
    ];
    home.stateVersion = "22.11"; # To figure this out (in-case it changes) you can comment out the line and see what version it expected.
    programs.home-manager.enable = true;
}

Now you can refer to the home-manager docs for other configuration options (of which there are many).

In the future I may write a post about my dotfiles and suggestions for others once I’ve had a chance to work on it a bit.