Opinionated defaults. This repo is not meant to be used by everyone, just a personal configuration to take ideas out of. However, if you are brave enough you can install it with the instructions below. You are advised to read the installation scripts beforehand.
You might wonder why the repository isn't just cloned directly into ~/dotfiles. The nested ~/dotfiles/dotfiles structure is required by how GNU Stow manages packages. Stow expects a "stow directory" (the parent, ~/dotfiles) containing one or more "packages" (the child, dotfiles, which is this repo).
By cloning into ~/dotfiles/dotfiles, stow correctly treats the inner dotfiles folder as the package name, allowing it to safely symlink the contents (like .config/, .vim/) directly into your $HOME directory without confusing the repository root with the target deployment.
So, the structure looks like this:
~/dotfiles/
└── dotfiles/ (this repo)
├── .config/ ──┐
├── .local/ │ GNU Stow symlinks
├── .vim/ ├──────────────────► $HOME/
├── .xmonad/ │ ├── .config/ → ~/dotfiles/dotfiles/.config/
├── .zshenv ──┘ ├── .local/ → ~/dotfiles/dotfiles/.local/
├── Makefile (make targets) └── ...
└── .local/scripts/
└── bootstrap/ (OS-specific setup)
GNU Stow creates symlinks from $HOME
into this repo so that every config file stays version-controlled in one place.
The Makefile wraps stow and exposes common tasks. Bootstrap scripts install
packages and perform one-time setup for each supported OS.
The $DOTFILES variable (exported by .zshenv) points to the repo root,
auto-detected by resolving the .zshenv symlink. Scripts and configs that
need to reference the repo should use $DOTFILES.
Clone the repo with its submodules and use GNU Stow to symlink everything into $HOME:
cd ~
mkdir -p dotfiles
git clone --recurse-submodules https://github.com/cuberhaus/dotfiles dotfiles/dotfiles
cd dotfiles/dotfiles
make installIf you don't have
stowinstalled, grab it first:
- Arch/Manjaro:
sudo pacman -S stow- Ubuntu/Debian:
sudo apt install stow- macOS:
brew install stow
Common tasks are available via make:
make help # Show all targets
make install # Symlink dotfiles into $HOME
make uninstall # Remove symlinks from $HOME
make restow # Re-stow (cleans stale links)
make lint # Run shellcheck on all scripts
make check # Run all linters (shellcheck + markdownlint + vint)
make submodules # Init and update submodules
make update # Pull latest for every submodule
make skip-worktree # Ignore runtime changes to volatile config files (run once after cloning)
make bootstrap-<os> # Run bootstrap (arch, manjaro, ubuntu, mac, work)
Some tracked files (e.g. user_preferences.json for Warp, javasettings_Linux_X86_64.xml for LibreOffice) are rewritten by their apps on every launch. They are kept in the repo so the settings you care about are versioned, but the constant runtime changes make git status noisy and block git pull.
After cloning, run once:
make skip-worktreeThis applies git update-index --skip-worktree to those files — git keeps the committed version but stops noticing local changes.
When you intentionally want to update one of them in the repo:
git update-index --no-skip-worktree .config/warp-terminal/user_preferences.json
# edit / copy the new settings you want to keep
git add .config/warp-terminal/user_preferences.json
git commit -m "update warp settings"
git update-index --skip-worktree .config/warp-terminal/user_preferences.json # re-applyOS-specific bootstrap scripts live in .local/scripts/bootstrap/.
Read the script for your OS before running it — they install hundreds
of packages and change system settings.
make bootstrap-arch # Arch
make bootstrap-manjaro # Manjaro
make bootstrap-ubuntu # Ubuntu
make bootstrap-mac # macOS
make bootstrap-work # Work machine (Ubuntu + NVIDIA, minimal)Each bootstrap entrypoint follows the same pattern:
- Sources
base_functions(shared logging helpers and$DOTFILESauto-detection). - Sources the OS-specific
*_functionsfile (package lists and installer functions). - Asks whether this is a first-time install (enables services, sets up hardware, etc.).
- Runs a system update.
- Calls installer functions in dependency order (base packages, WM-specific, optional apps).
- Switches the default shell to zsh.
See .local/README.md for a detailed breakdown of the
scripts directory.
| Category | Tool / Config | Notes |
|---|---|---|
| Shells | zsh (antigen, p10k), bash | XDG-compliant $ZDOTDIR in .config/zsh/ |
| Editors | Vim, Neovim, Doom Emacs, personal Emacs (chemacs) | Vim config at .vim/vimrc; Emacs literate config in .config/emacs.org |
| Terminals | kitty, Alacritty, termite | |
| Window Managers | XMonad (+xmobar), i3 (+i3blocks +polybar), qtile, sway | XMonad is the primary config; i3 is the secondary |
| Desktop Environments | Cinnamon, GNOME | |
| Utilities | tmux, ranger, dunst, picom, rofi, fzf, bat, eza | |
| Themes | Arc, Dracula, OneDark, base16 | Managed via toggle_theme script |
- Xmonad (Main config)
- i3 (Second best)
- Cinnamon desktop
- Gnome



