My personal dotfiles for Ubuntu 26.04 LTS, Hyprland and Zsh, with Catppuccin Mocha as the main theme. Feel free to browse and reuse individual settings.
The configuration is organised into GNU Stow packages. Each package mirrors its destination under $HOME: for example, ghostty/.config/ghostty/config becomes ~/.config/ghostty/config.
Clone the repository and install Stow:
sudo apt install git stow
git clone https://github.com/never-rain/dotfiles.git "$HOME/dotfiles"
cd "$HOME/dotfiles"Run bash install.sh as your normal user. The script asks about each step separately; press Enter or answer j/ja (also y/yes) to proceed, or answer n/nein (also no) to skip:
- Add the GitHub CLI APT repository.
- Add the Griffo APT repository.
- Refresh the APT package indexes and install the packages from
packages.txt, includingghandstarship. - If Zsh is installed, offer to make it the current user's login shell with
chsh. An account already using Zsh is skipped. This may ask for your password and takes effect after fully logging out and back in. - Install fnm using its official installer into
~/.local/share/fnm. An existing fnm inPATHor at that location is skipped. Missingcurl/unzipprerequisites are offered separately. The installer runs with--skip-shellbecause the Zsh dotfiles already initialise fnm; it does not append to.bashrcor.zshrc. - Install pnpm using its official standalone installer, with
PNPM_HOME=~/.local/share/pnpm. An existing pnpm is skipped. Missingcurl,tar,gzipandopensslare offered separately. The installer's shell configuration is directed into a temporary file because the Zsh dotfiles already set the pnpm paths. - Install Codex CLI with
pnpm add --global @openai/codex, withoutsudo. pnpm is available immediately after step 6; no new terminal is needed. Before installing or checking Codex, the script ensures Node.js runs: it uses an existing Node or activates fnm's default version in the running Bash process. If no default is usable, it offers to install Node LTS with fnm and make it the default for future terminals. Declining, missing fnm when Node is unavailable, or missing pnpm skips the Codex step. An existingcodexcommand is checked with--versionrather than reinstalled. Sign in separately when you first runcodex. - Install Zap for Zsh by cloning its
release-v1branch into${XDG_DATA_HOME:-$HOME/.local/share}/zap. An existing Zap directory is skipped. This does not modify or source.zshrc, so installation also works before Stow has linked your shell configuration. - Link all Stow packages into your home directory. The script lists the packages and target before asking for confirmation, then checks for conflicts with a simulation before creating links.
- Optionally start Zsh with
exec zshto load the shell settings in the current terminal. Enter confirms this step;nskips it. Temporary downloads are cleaned up before replacing the installer process. This does not log you out or restart the desktop session. When launched withbash install.sh, exiting the new Zsh returns to the shell that started the installer.
Missing prerequisites are offered as a separate, confirmed APT installation before the step that needs them. Declining skips that step. APT may also ask for confirmation. Errors stop the script, including failed index downloads from temporarily unavailable APT sources; completed changes are not rolled back.
packages.txt contains one package name per line. Leading and trailing whitespace (including Windows line endings) is removed; blank lines and lines starting with # are ignored. The entire list is selected as one step; edit it beforehand to choose individual packages. Package availability depends on your distribution and enabled sources, including when you skip adding a repository. Repository setup alone does not refresh APT indexes; that happens in the package step.
Existing GitHub CLI and Griffo entries in standard APT .list and .sources files are detected and left in place. This does not verify their signing keys or repair an existing setup. The script uses sudo for package and repository changes; chsh and Stow run as your normal user. The shell step checks the account entry and /etc/shells, then verifies the new account entry after chsh succeeds.
Every non-hidden directory directly inside this repository is treated as a Stow package; keep unrelated directories outside the checkout. Stow always targets $HOME, regardless of where you cloned the repository, and uses its default behaviour of linking whole directories where possible. Existing correct links are kept. Conflicting files (for example an existing ~/.zshrc) are reported without being overwritten or adopted into the repository. If the simulation fails, no links are created: inspect the reported files, back up/move them yourself if appropriate, then rerun the script. You can skip the installation steps and select only Stow.
The script retains deb.griffo.io from the original setup. Griffo announces that package downloads require a subscription from 1 October 2026; its free mirror has a smaller package selection. Existing entries using debian.griffo.io are also recognised.