JustToThePoint English Website Version
JustToThePoint en español

NixOS III. Home Manager

If you’re going through hell, keep on going, Winston Churchill

NixOS is a unique, innovative, and powerful Linux distribution that leverages the Nix package manager. Unlike traditional Linux distributions that update packages and system configurations in-place, NixOS uses a purely functional and declarative approach to define the system state, reducing the risk of system breakage.

NixOS is a Linux distribution that uses the Nix package manager to handle packages and system configuration in a purely functional manner. This approach ensures that builds are reproducible and that the system state can be reliably replicated or rolled back.

  1. Immutable Design: It uses a configuration file (usually /etc/nixos/configuration.nix) to define the entire system state, including installed packages, services, and system settings. This makes the system “immutable” in the sense that you don’t manually modify system files. Instead, you declare what you want, and NixOS builds the system from that declaration.
  2. Atomic Updates: When you run nixos-rebuild switch, the system builds a new generation of the environment. If the build is successful, you can switch to this new environment atomically. This means that either the entire update is applied, or nothing changes at all, preventing partial updates that could leave the system in an inconsistent state: sudo nixos-rebuild switch, build and switch to the new generation. If anything goes wrong, you can easily roll back to a previous generation: sudo nix-env ‐‐rollback This rollback is seamless because each generation is stored separately.

    sudo nix-env ‐‐rollback is a command used to revert your system to the previous configuration. It’s a powerful tool for undoing unintended changes or recovering from failed package installations. Before rolling back, consider if there’s a more targeted solution, like uninstalling specific packages or reverting configuration files.

  3. Purely Functional System Configuration: NixOS uses a functional paradigm for configuration. This means that changes are expressed as pure functions from a configuration to a system state, ensuring reproducible builds and easy rollback.

NixOS

Home Manager

Home Manager is a separate NixOS tool that manages user-specific configuration independently of the system configuration (system services, globally installed packages, and system-wide settings). It follows the same declarative approach as NixOS, allowing you to manage dotfiles (files like .zshrc, .config/i3/config, .config/picom/picom.conf), environment variables, user-level services and packages, and more in a structured and reproducible way.

It is a better way to manage your dotfiles. Let’s enable Home Manager as a NixOS module.

Enabling Home Manager as a NixOS Module

First, we are going to add the Home Manager channel. Channels are references to collections of Nix expressions. They tell Nix where to fetch packages and configurations from.

# Add Home Manager's channel
nix-channel --add https://github.com/nix-community/home-manager/archive/master.tar.gz home-manager
# This sets up a channel named home-manager following Nixpkgs master.

# Update our channels. This command fetches the latest changes from the channels we have subscribed to.
sudo nix-channel --update

# Since we’re using Home Manager as a NixOS module (integrate into configuration.nix or a separated file imported by it),
# we just need to rebuild the system to update all channels (apply the updates):
sudo nixos-rebuild switch
# After this step, Home Manager is ready to be used alongside the system configuration.

# To list all channels that are available in our system:
sudo nix-channel --list
# To remove a channel, type the following command:
sudo nix-channel --remove channel-alias
# Replace channel-alias with the name of the channel you want to remove.
Ensure that Home Manager’s home.stateVersion (~/dotfiles/home.nix: home.stateVersion = “25.05”;) and NixOS’s system.stateVersion (sudo vim /etc/nixos/configuration.nix/: system.stateVersion = “25.05”;) match.

We are going to create a dotfiles directory, and inside it a HomeManager configuration file: ∼/dotfiles/home-manager.nix. Below is a Home Manager configuration file:

{ config, pkgs, ... }:

{
  # This command allows using global packages to avoid duplications
  home-manager.useGlobalPkgs = true;
  home-manager.useUserPackages = true; # Enables user-specific packages in Home Manager.
  home-manager.backupFileExtension = "backup"; # Extension for backup files generated by Home Manager

  # Configuration settings for the user 'nmaximo7'
  home-manager.users.nmaximo7 = { pkgs, ... }:
  let # It uses a let expression to define variables (username, dotfiles) so we can reuse it throughout the configuration.
    username = "nmaximo7";  # Set the username variable
    dotfiles = "/home/${username}/dotfiles"; # Path to the user's dotfiles directory
  in {
    # User-level packages to be installed via Home Manager
    home.packages = with pkgs; [
      cowsay # Fun command-line utility that generates ASCII art.
      fastfetch # An actively maintained, feature-rich neofetch like system information tool.
      lshw # Hardware listing tool.
      # Add more user-level packages as desired or needed.
    ];

    home.stateVersion = "25.05";  # Specify the version of Home Manager. Remember to update it as needed for compatibility

    home.username = username; # Set the Home Manager's username
    home.homeDirectory = "/home/${username}"; # Set the user's home directory path

    # Include other configuration files from the dotfiles directory
    imports = [
      "${dotfiles}/shell.nix" # Shell configuration
      "${dotfiles}/kitty.nix" # Kitty terminal configuration
      "${dotfiles}/zsh.nix" # Zsh shell configuration
      "${dotfiles}/alacritty.nix" # Alacritty terminal configuration
      "${dotfiles}/rofi.nix" # Rofi application launcher configuration
      "${dotfiles}/vscode.nix" # VSCode configuration
      # Add other configuration files as needed
    ];

    # Enable Home Manager to manage its own configuration
    programs.home-manager.enable = true;

    # Links to Espanso, i3, i3status, Picom, and Fastfetch configuration files
    home.file.".config/espanso/match/base.yml".source = "/home/${username}/dotfiles/base.yml";
    home.file.".config/i3/config".source = "/home/${username}/dotfiles/i3/config";
    home.file.".config/i3status/i3status.conf".source = "/home/${username}/dotfiles/i3/i3status.conf";
    home.file.".config/picom/picom.conf".source = "/home/${username}/dotfiles/i3/picom.conf";
    home.file.".config/fastfetch/config.jsonc".source = "/home/${username}/dotfiles/fastfetch/config.jsonc";
  };
}

Neovim

Neovim is a modern, hyperextensible Vim-based text editor. vim-plug is a minimalist Vim plugin manager, vim ~/dotfiles/nvim.nix. With Home Manager, we can declaratively configure Neovim plugins, settings, and themes.

This configuration is a Nix expression that sets up Neovim with specific settings, plugins, and Python support.

{ config, pkgs, ... }:

{
  programs.neovim = {
    # Ensure Neovim is installed and enabled in your NixOS system.
    enable = true;

    # Specify the Neovim package version and enable Python support
    withPython3 = true;
    extraPython3Packages = ps: with ps; [ pynvim ];

    # Configuration for Neovim
    extraConfig = ''
      " Set leader key
      let mapleader = " "  " Use space as the leader key

      " General settings
      set number " Show line numbers
      set relativenumber " Show relative line numbers
      set tabstop=4 " Number of spaces per tab
      set shiftwidth=4 " Number of spaces for autoindent
      set expandtab " Convert tabs to spaces
      set nowrap " Disable line wrapping

      " Enable syntax highlighting
      syntax on

      " Set the colorscheme to gruvbox
      colorscheme gruvbox

      " Key mappings
      nnoremap n :NERDTreeToggle  " Toggle NERDTree
      nnoremap f :FZF  " Open FZF
    '';

    # Specify additional plugins if needed
    plugins = with pkgs.vimPlugins; [
      # Add any additional plugins here
      vim-sensible # This is a collection of default settings and sensible defaults for Vim.
      nerdtree # A file explorer plugin for Vim/Neovim that provides a tree view of your files and directories.
      fzf-vim # A Vim plugin that integrates fzf, a fast fuzzy file finder.
      # It allows users to quickly search for files, buffers, and more using fuzzy matching.
      gruvbox
      # A popular color scheme for Vim/Neovim that provides a warm, retro aesthetic with good contrast.
    ];
  };
}

After opening Neovim (nvim), you can use the defined key mappings:

SHELL Configuration

You can store your shell environment variables, defaults, and locales in a shell.nix file:

{ config, pkgs, ... }:

let
  # Reference to the home configuration from NixOS
  home = config.home;
in
{
  # Sets environment variables for the user's login session
  home.sessionVariables = {
    # Set the default text editor to Neovim
    EDITOR = "nvim";

    # Set the visual editor (used by some applications) to Neovim
    VISUAL = "nvim";

    # Set the default language for the environment to US English
    LANG = "en_US.UTF-8";

    # Set the default web browser to Firefox
    BROWSER = "firefox";

    # Set the default terminal to Alacritty
    TERMINAL = "alacritty";
  };

  # Configuration for Zsh will be imported from an external file `zsh.nix`
}
Bitcoin donation

JustToThePoint Copyright © 2011 - 2025 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.