Effortlessly Manage Dotfiles on Unix-based Systems with GNU Stow and GitHub

Effortlessly Manage Dotfiles on Unix-based Systems with GNU Stow and GitHub

Managing dotfiles—your personal configuration files for shells, editors, and tools—can quickly become a disorganized mess, especially across multiple systems. Enter GNU Stow, a powerful symlink farm manager that lets you organize, version control, and deploy your dotfiles with ease. This post walks you through a practical workflow, letting you focus less on symlink headaches and more on productivity.

There are more complete and complex tools like Chezmoi to manage system configurations, but I like the simplicity and full reversibility of stow.

Here is a short comparison between the two:

The main difference between chezmoi and stow lies in their approach, features, and flexibility in managing dotfiles and configuration files across different systems.

Chezmoi

  • Purpose: Designed specifically for managing personal configuration files (dotfiles) across multiple, diverse machines securely and conveniently.
  • Features:
    • Stores your configuration in a single source of truth (like a Git repository).
    • Supports advanced features such as templates (to manage machine-specific differences), integration with password managers, full file encryption (gpg, age), the ability to run scripts on installation, and importing files from archives.
    • Makes it easy to keep secrets out of your repository and supports secure automation.
    • Cross-platform with binary releases for all major operating systems and simple installation/update workflow.
    • Updates and setups are as simple as one command: chezmoi update.
  • Best for: Users who want a highly automated, templatable, cross-platform dotfiles solution with built-in support for securely managing secrets and handling environment differences.

Stow

  • Purpose: A general-purpose "symlink farm manager," originally intended to manage separate packages (e.g., local software builds) but also widely used for dotfile management.
  • How it works: You organize your dotfiles into directories ("packages") and Stow creates symlinks to those files in their intended locations (like your home folder).
  • Features:
    • Simplicity—no database or extra state, only symlinks.
    • Clean, reversible operations for linking and unlinking packages.
    • Mostly used in UNIX-like environments.
    • No built-in templates or secret management—secrets must be handled separately.
    • Minimal dependencies, usually a Perl script.
  • Best for: Users who want a simple, lightweight, UNIX-friendly way to symlink dotfiles without extra layers or automation.

Key Differences

chezmoi stow
Focus Dotfile management, secrets, cross-platform support General-purpose symlink manager
Templates Yes (handle machine-specific configs) No
Secret Handling Yes (integrates with password managers, encryption) No (manual)
Automation Yes (scripts at install/update) No
Cross-platform Yes UNIX-like only
Complexity Higher, but powerful Very simple
Symlink-based Applies changes/copies as necessary Pure symlink manager
  • Chezmoi shines when you need advanced features, cross-platform compatibility, and care about template or secrets management as part of your workflow.
  • Stow is elegant in its simplicity and ideal if you only need to symlink files in a consistent, reversible way, especially in a Linux-only or UNIX-focused environment.

For complex, modern dotfile management (especially with secrets or templates across systems), chezmoi is generally more powerful and flexible. If you just want a no-fuss way to link your files, stow remains a trusted classic.

Why Use GNU Stow?

Traditionally, people managed dotfiles by manually creating symbolic links or writing custom scripts. This quickly leads to chaos. GNU Stow automates this by using a directory structure that mirrors your $HOME, creating the required symlinks in a single command. This structure plays exceptionally well with version control tools like Git, so you can keep your configuration portable and synchronized across many machines.

Step 1: Set Up Your Dotfiles Directory

Create a central directory (commonly ~/dotfiles) to store all your dotfiles.

mkdir -p ~/dotfiles

Move or copy your existing dotfiles (e.g., .zshrc, .vimrc) into this directory, preserving the directory structure as it exists in your home directory:

mkdir -p ~/dotfiles
mv ~/.zshrc ~/dotfiles

For dotfiles located in hidden folders, mirror the hierarchy:

mkdir -p ~/dotfiles/.config/nvim
mv ~/.config/nvim/* ~/dotfiles/.config/mvim/

Remove or backup the originals if you copied them:

mv ~/.zshrc ~/.zshrc.backup

Step 2: Have Stow ignore Files that shouldn't be Symlinked

If you are using a Mac, you don't want symlinks from .DS_Store files created in the dotfiles folder by Finder in your root folder. (Stow wouldn't create them anyway but would complain and fail when asked to create symlinks later).

Create a .stow-local-ignore file in ~/dotfiles

As this removes all the default ignores, you'll have to add the default ignores to it plus the files you want to ignored in addition. Here is the full file that includes the added .DS_Store files:

# Comments and blank lines are allowed.

RCS
.+,v

CVS
\.\#.+       # CVS conflict files / emacs lock files
\.cvsignore

\.svn
_darcs
\.hg

\.git
\.gitignore
\.gitmodules

.+~          # emacs backup files
\#.*\#       # emacs autosave files

^/README.*
^/LICENSE.*
^/COPYING

.DS_Store

Install Stow using your system’s package manager:

# Ubuntu/Debian
sudo apt-get install stow

# macOS
brew install stow

# Arch
sudo pacman -S stow

Run GNU Stow from within your dotfiles directory for the package (subfolder) you want to deploy:

cd ~/dotfiles
stow .

Stow will create symlinks in your home directory, pointing back to the versions in ~/dotfiles.

Step 3: Manage with Git (and GitHub)

Initialize a Git repository in your dotfiles directory:

cd ~/dotfiles
git init
git add .
git commit -m "Initial commit of my dotfiles"

Create a remote repository on GitHub (preferably private to avoid leaking secrets or credentials).

Push your changes:

git remote add origin git@github.com:yourusername/dotfiles.git
git push -u origin main

Set up a .gitignore as needed (GNU Stow already ignores .git internally, but you may have other files to ignore):

echo ".DS_Store" >> .gitignore

Advanced Usage Tips

  • Use stow --adopt to safely migrate existing files into your dotfiles directory if conflicting files don't already exist.
  • If you edit a symlink managed by stow, i.e. nvim /.zshrc~ you'll actually be editing the real file in the ~/dotfiles folder.
  • Add a README.md in your dotfiles repo explaining dependencies and installation—handy when setting up on a new system.
  • The default Stow ignore rules already skip .git, but you can tailor your own ignore files for more control.
  • Always commit changes before using advanced options like --adopt to protect against unwanted overwrites.

Why This Workflow?

This approach is:

  • Modular—easily manage configs for multiple apps or environments.
  • Portable—move your setup between machines with a simple git clone and stow.
  • Versioned—roll back configurations with Git if something breaks.
  • Safe—symlinks keep your files organized, and Git with GitHub gives you an off-site backup.

Final Thoughts

GNU Stow, combined with GitHub, makes dotfile management frictionless and robust—no more manual symlinking or loss of configs on new machines. This approach is clean, scalable, and integrates perfectly into a DevOps or cloud-first workflow.

Give it a shot and enjoy never losing your custom shell setup again!