Modular dotfiles for Zsh and Fish. One repo, both shells configured, switch anytime.
| Zsh (~35ms) | Fish (~8ms) | |
|---|---|---|
| Autosuggestions | match_prev_cmd → history → completion via plugin |
Built-in |
| Syntax highlighting | Turbo-loaded plugin | Built-in |
| Completions | fzf-tab + zsh-completions | Built-in |
| Plugins needed | 4 (managed by Zinit) | 0 |
| Config style | Modules assembled into single .zshrc |
conf.d/ + functions/ |
Shared: Starship prompt, zoxide, lazy-loaded NVM, compiled .zshrc bytecode, --dry-run mode, non-interactive/CI support, backup merge flow.
git clone https://github.com/purian23/zdots.git ~/.zdots
cd ~/.zdots
./setup.sh # configures both shells
./setup.sh --dry-run # preview onlyBoth shells are installed if missing. Switch anytime with zsh or fish.
Auto-detects: pacman, apt, dnf, zypper, yum, apk, nix-env, xbps-install, emerge, Homebrew.
Tested on Arch, Ubuntu, Fedora 43, Alpine, macOS.
| Variable | Purpose |
|---|---|
ZDOTS_YES=1 |
Answer yes to all prompts |
ZDOTS_NO=1 |
Answer no to all prompts |
ZDOTS_NONINTERACTIVE=1 |
Use defaults, skip chsh |
ZDOTS_PM=<name> |
Force a package manager |
ZDOTS_MERGE=all|yes|no |
Control backup merge |
ZDOTS_LOGFILE=<path> |
Override log path |
time zsh -i -c exit # ~0.035s
time fish -c exit # ~0.008sProfile Zsh: add zmodload zsh/zprof to top of .zshrc, run zprof.
"terminal.integrated.profiles.linux": {
"zsh": { "path": "/bin/zsh", "args": ["-l"] },
"fish": { "path": "/usr/bin/fish", "args": ["-l"] }
},
"terminal.integrated.defaultProfile.linux": "zsh"Not auto-installed: bat, eza, fzf, p7zip, starship, unrar, unzip, zoxide.
# Zsh — restore backup
mv ~/.zshrc ~/.zshrc.generated.bak
mv ~/.zshrc.bak.YYYYMMDDHHMM ~/.zshrc
# Fish — remove zdots configs
rm ~/.config/fish/conf.d/{00-options,10-path,20-nvm,30-prompt,40-zoxide,99-extras}.fish
rm ~/.config/fish/functions/{nvm,node,npm,npx}.fish
# Remove repo
rm -rf ~/.zdotsPRs welcome. Priorities: clarity, speed, portability.