Portable CLI/development configuration managed with GNU Stow. The default install is safe for headless systems, SSH-only hosts, containers, and general Linux/macOS machines.
Desktop/Wayland configuration is opt-in through profiles and should eventually live in a separate dotfiles-desktop repo. Fedora Asahi hardware/system recovery should stay in asahi-dotfiles.
curl -fsSL https://raw.githubusercontent.com/fjordnode/dotfiles/main/bootstrap.sh | bashThe default profile is cli and only stows portable terminal/dev config.
# Portable CLI/dev config only
PROFILE=cli bash bootstrap.sh
# CLI/dev plus AI tool config
PROFILE=dev bash bootstrap.sh
# Explicit desktop installs
PROFILE=desktop-niri bash bootstrap.sh
PROFILE=desktop-hypr bash bootstrap.sh
PROFILE=desktop bash bootstrap.sh
# Transitional Asahi profile; system recovery belongs in asahi-dotfiles
PROFILE=asahi bash bootstrap.shProfile packages:
cli:zsh,tmux,git,nvim,starship,eza,bat,yazi,scriptsdev:cliplusclaudedesktop-niri:devpluskitty,ghostty,niri,noctalia,noctalia-v5desktop-hypr:devpluskitty,ghostty,hypr,noctalia,noctalia-v5desktop: both desktop compositor configsasahi: transitional profile with desktop config andvpn-split; Asahi hardware/system recovery lives in~/asahi-dotfiles
Desktop profiles also install the main runtime packages they depend on when the system package manager is supported. On Arch/CachyOS, PROFILE=desktop-niri installs common Wayland/Niri tools such as wl-clipboard, cliphist, wtype, brightnessctl, playerctl, pavucontrol, kitty, firefox, satty, and available Niri portal/session packages.
Noctalia v5 note: this repo tracks config and a noctalia-v5 launcher wrapper, but does not install the alpha v5 shell itself. Install or update v5 from upstream docs: https://docs.noctalia.dev/v5/getting-started/installation. If you are building v5 from source, you can ask the bootstrap to install known build dependencies with INSTALL_NOCTALIA_V5_DEPS=1 PROFILE=desktop-niri bash bootstrap.sh.
Fresh CachyOS/Niri desktop example:
curl -fsSL https://raw.githubusercontent.com/fjordnode/dotfiles/main/bootstrap.sh | PROFILE=desktop-niri bashFor Termux on Android devices:
curl -fsSL https://raw.githubusercontent.com/fjordnode/dotfiles/main/bootstrap-android.sh | bashThis will:
- Install all required packages using
pkg(Termux package manager) - Set up Android storage access
- Clone this repository to
~/dotfiles - Create symlinks using GNU Stow
- Install oh-my-zsh with plugins (autosuggestions, syntax-highlighting, completions)
- Install Starship prompt
- Create zsh launcher script (since
chshis not available) - Configure Termux-specific optimizations
If you prefer to see what's happening:
# Download the bootstrap script
curl -fsSL https://raw.githubusercontent.com/fjordnode/dotfiles/main/bootstrap.sh > bootstrap.sh
# Review it
cat bootstrap.sh
# Run it
bash bootstrap.sh# Download the Termux bootstrap script
curl -fsSL https://raw.githubusercontent.com/fjordnode/dotfiles/main/bootstrap-android.sh > bootstrap-android.sh
# Review it
cat bootstrap-android.sh
# Run it
bash bootstrap-android.sh- zsh - Shell configuration with oh-my-zsh
- nvim - Neovim configuration with Lazy.nvim and plugins
- tmux - Terminal multiplexer configuration
- git - Git configuration and aliases
- bat/eza/yazi - CLI tool configuration
- starship - Cross-shell prompt
- claude - AI tool configuration, installed by
PROFILE=devor desktop profiles - niri/hypr/noctalia - Desktop-only config, installed only by explicit desktop profiles
- scripts - Portable helper scripts used by shell, tmux, and Neovim profiles
- vpn-split - Transitional Linux-specific VPN helpers, installed only by
PROFILE=asahi
dotfiles/
βββ zsh/
β βββ .zshrc
βββ nvim/
β βββ .config/
β βββ nvim/
β βββ init.lua
β βββ lua/
βββ tmux/
β βββ .tmux.conf
βββ git/
β βββ .gitconfig
βββ starship/
β βββ .config/
β βββ starship.toml
βββ bat/
βββ eza/
βββ yazi/
βββ claude/ # dev profile
βββ niri/ # desktop profiles
βββ hypr/ # desktop profiles
βββ noctalia*/ # desktop profiles
βββ scripts/ # portable helper scripts
βββ vpn-split/ # asahi transitional profile
After installation, your config files are symlinked from ~/dotfiles. To update configs:
- Edit the files in
~/dotfiles/[package]/ - Commit and push changes:
cd ~/dotfiles
git add .
git commit -m "Update configs"
git pushTo update your dotfiles on another machine:
cd ~/dotfiles
git pull
PROFILE=cli ./bootstrap.shThe bootstrap script supports several environment variables:
# Skip full install (only core packages)
FULL_INSTALL=0 bash bootstrap.sh
# Skip oh-my-zsh installation
INSTALL_OMZ=0 bash bootstrap.sh
# Skip starship installation
INSTALL_STARSHIP=0 bash bootstrap.sh
# Skip setting zsh as default shell
SET_DEFAULT_SHELL=0 bash bootstrap.sh
# Install a specific profile
PROFILE=desktop-niri bash bootstrap.shTo add a new program's configuration:
- Create a new directory in
~/dotfiles - Mirror the expected structure from
$HOME - Add it to the correct profile in
bootstrap.sh
Example for adding vim config:
cd ~/dotfiles
mkdir -p vim
mv ~/.vimrc vim/.vimrc
stow -t "$HOME" vim
git add vim
git commit -m "Add vim configuration"The vpn-split package is Linux-specific and is not part of the default cli profile. It stows:
~/.local/bin/novpn~/.local/bin/wg-split-up~/.local/bin/wg-split-down~/.local/bin/wg-kill-switch-off~/.local/bin/wg-status-proton~/.local/bin/wg-status-home~/.local/bin/wg-status-killswitch~/.local/bin/wg-toggle-proton~/.local/bin/wg-toggle-home~/.local/bin/wg-toggle-killswitch~/.config/systemd/user/novpn.slice~/.config/systemd/user/novpn-anchor.service~/.local/share/wg-split-tunnel/50-wg-split-tunnel~/.local/share/wg-split-tunnel/wg-split-tunnel.md
Root-managed files still need a manual install step:
sudo install -m 755 ~/.local/share/wg-split-tunnel/50-wg-split-tunnel \
/etc/NetworkManager/dispatcher.d/50-wg-split-tunnelYou may also want to name table 26642 in /etc/iproute2/rt_tables:
echo '26642 novpn' | sudo tee -a /etc/iproute2/rt_tablesIf stow reports conflicts, move the existing files aside first:
mv ~/.zshrc ~/.zshrc.backup
mv ~/.tmux.conf ~/.tmux.conf.backup
cd ~/dotfiles
PROFILE=cli ./bootstrap.shIf zsh plugins aren't working:
git clone https://github.com/zsh-users/zsh-completions ~/.oh-my-zsh/custom/plugins/zsh-completions
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlightingIf Neovim plugins aren't installed:
nvim --headless "+Lazy! sync" +qa- Linux (Debian/Ubuntu, Fedora/RHEL, Arch, openSUSE)
- macOS (with Homebrew)
- Termux (Android)
- Docker containers
- Unraid (via Docker container)
MIT