One of the things I love most about NixOS is that once you get something working, it is reproducible everywhere. This post covers how I wired up Alacritty, tmux, and Zsh with Oh My Zsh into a single shared home-manager module that applies across all my machines.
The setup
All my machines share a home/modules/base.nix file that is imported into each host’s home-manager configuration. The goal was a terminal experience that:
- Opens directly into a persistent tmux session
- Uses Zsh with syntax highlighting and autosuggestions
- Uses the
kali-likeOh My Zsh theme, pinned by hash
Alacritty launches straight into tmux
Instead of landing at a bare shell, Alacritty is configured to start tmux and attach to (or create) a named session:
programs.alacritty = {
enable = true;
settings = {
terminal.shell = {
program = "tmux";
args = [ "new-session" "-A" "-D" "-s" "main" ];
};
font.size = 14.0;
};
};
The flags mean:
-A— attach if the session already exists-D— detach any other client connected to that session-s "main"— session name
This means every time you open Alacritty, you land in the same persistent session. Close the window, reopen it, and you are right back where you were.
Tmux config
Mouse support and a sane scroll behaviour are the main additions. By default tmux scroll can be awkward — this config makes it so that scrolling up enters copy mode, and scrolling down exits it naturally:
programs.tmux = {
enable = true;
mouse = true;
terminal = "xterm-256color";
extraConfig = ''
unbind -T root WheelUpPane
unbind -T root WheelDownPane
bind -n WheelUpPane if-shell -F '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e; send-keys -M'
bind -n WheelDownPane if-shell -F '#{pane_in_mode}' 'send-keys -M' 'send-keys -M'
'';
};
Zsh with Oh My Zsh
Home-manager handles the Zsh configuration, including the plugins and theme. The syntax highlighting and autosuggestions packages are installed by Nix, so they are available before the theme tries to load them:
programs.zsh = {
enable = true;
syntaxHighlighting.enable = true;
autosuggestion.enable = true;
oh-my-zsh = {
enable = true;
plugins = [ "git" "z" ];
theme = "kali-like";
custom = "${config.home.homeDirectory}/.local/share/omz-custom";
};
};
The custom path points to a directory where home-manager drops the theme file.
Pinning the theme by hash
The kali-like theme is not in the Oh My Zsh theme collection, so it is fetched from GitHub at build time and placed in the custom themes directory:
home.file.".local/share/omz-custom/themes/kali-like.zsh-theme".source = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/clamy54/kali-like-zsh-theme/main/kali-like.zsh-theme";
hash = "sha256-uoOJ4/9YN9TbQBODZxi0GJwDHh0OtpUnoTynIAqmVGg=";
};
If the hash ever needs updating (e.g. after the theme file changes upstream), run:
nixos-rebuild build --flake .#<host> 2>&1 | grep "got:"
and replace the hash with the one reported.
One module, all machines
Because this lives in home/modules/base.nix and is imported by every host, updating a single file propagates to all machines on the next rebuild. That is the real win — no drift, no manual setup.
home/
modules/
base.nix ← shared config (this post)
hosts/
host1.nix
host2.nix
...
Each host file imports base.nix and adds only what is host-specific.
One side effect worth knowing
Because Alacritty always launches inside tmux, and the kali-like theme detects the $TMUX environment variable, your prompt will always show a (tmux) indicator. It is not a bug — it is just the theme doing its job. Honestly, I can live with it.
Written With AI