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.
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.

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.
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.
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 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:
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`
}