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
Step 3: Use Stow to Symlink Dotfiles
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
andstow
. - 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!