GuideApril 7, 20267 min read

Switching from GNU Stow to ConfigSync

GNU Stow has served you well, but your dotfile needs have outgrown symlinks. Here's how to migrate to ConfigSync with encryption, cloud sync, and zero symlink headaches.

Why Move Beyond Stow?

GNU Stow is a beautifully simple tool. You organize your dotfiles into directories, and Stow creates symlinks from those directories to your home directory. It is elegant, it is minimal, and for many developers it was the first dotfile manager they ever used.

But Stow was designed in 1993 as a general-purpose symlink farm manager. It was never built specifically for dotfiles, and it shows. There is no encryption, no cloud sync, no secrets management, and no templating. If you want any of those features, you end up stitching together multiple tools — git for version control, GPG for encryption, a custom script for bootstrapping new machines.

ConfigSync replaces that entire stack with a single tool. Your configs are encrypted at rest, synced to the cloud with one command, and templates handle per-machine differences automatically. If you have been running Stow with a collection of shell scripts to fill the gaps, this migration will simplify your setup significantly.

Understanding the Architecture Difference

The key difference between Stow and ConfigSync is how they manage files.

Stow uses symlinks. Your actual files live in a directory like ~/dotfiles/zsh/.zshrc, and Stow creates a symlink from ~/.zshrc pointing to it. The file in your home directory is not a real file — it is a pointer to the one in your dotfiles directory.

Stow structure
~/dotfiles/ ├── zsh/ │ └── .zshrc # actual file lives here ├── git/ │ └── .gitconfig # actual file lives here ├── ssh/ │ └── .ssh/ │ └── config # actual file lives here └── vim/ └── .vimrc # actual file lives here # ~/.zshrc → symlink to ~/dotfiles/zsh/.zshrc

ConfigSync tracks files in place. Your .zshrc stays at ~/.zshrc as a regular file. ConfigSync knows where it is, monitors it for changes, and syncs encrypted copies to the cloud. No symlinks, no separate directory structure.

Why this matters: Symlinks can break when tools create new files instead of modifying existing ones (common with editors that use atomic saves), when Docker bind-mounts do not follow symlinks, or when backup tools skip symlinked files. ConfigSync avoids all of these issues.

Step-by-Step Migration

Step 1: List your Stow packages. Each directory in your dotfiles folder is a Stow package. List them to see what you are working with.

List Stow packages
ls ~/dotfiles/ # Output: git ssh vim zsh tmux alacritty starship

Step 2: Install ConfigSync.

Install and initialize
npm install -g @configsync/cli configsync init

Step 3: Map Stow packages to ConfigSync modules. Many common Stow packages correspond directly to ConfigSync modules. Modules track all related files for a tool automatically, so you do not need to add each file individually.

Add modules for common tools
# These modules know which files to track configsync add module zsh # .zshrc, .zshenv, .zprofile, etc. configsync add module git # .gitconfig, .gitignore_global configsync add module ssh # .ssh/config (keys handled separately) configsync add module vim # .vimrc, .vim/ configsync add module tmux # .tmux.conf

Step 4: Add remaining files individually. For Stow packages that do not map to a built-in module, add the config files directly.

Add individual config files
# For tools without a dedicated module configsync add config ~/.config/alacritty/alacritty.toml configsync add config ~/.config/starship.toml

Step 5: Remove Stow symlinks. Use Stow’s own uninstall command to remove the symlinks and restore the actual files to their proper locations.

Remove symlinks
cd ~/dotfiles # Unstow each package (removes symlinks, files stay in ~/dotfiles/) stow -D zsh stow -D git stow -D ssh stow -D vim stow -D tmux # Copy actual files to their expected locations cp ~/dotfiles/zsh/.zshrc ~/.zshrc cp ~/dotfiles/git/.gitconfig ~/.gitconfig # ... repeat for each file
Important: After unstowing, the files in your home directory will be gone (the symlinks are removed). You need to copy the actual files from your dotfiles directory to their proper locations. Verify each file is in place before proceeding.

Step 6: Push to ConfigSync.

Push your environment
configsync push -m "migrated from stow"

Stow Package to ConfigSync Module Mapping

Stow PackageConfigSync EquivalentCommand
zsh/zsh moduleconfigsync add module zsh
git/git moduleconfigsync add module git
ssh/ssh moduleconfigsync add module ssh
vim/vim moduleconfigsync add module vim
tmux/tmux moduleconfigsync add module tmux
neovim/neovim moduleconfigsync add module neovim
vscode/vscode moduleconfigsync add module vscode
alacritty/Individual fileconfigsync add config <path>
starship/Individual fileconfigsync add config <path>

What You Gain After Migrating

Encryption. Every file ConfigSync syncs is encrypted with AES-256-GCM before it leaves your machine. Stow has no encryption at all — if you push your dotfiles directory to GitHub, anything in those files is public.

Cloud sync. Push your environment from one machine and pull it on another with a single command. No git repository, no SSH keys, no merge conflicts.

No symlink issues. Files live in their original locations. No broken symlinks, no issues with Docker bind mounts, no problems with tools that do not follow symlinks.

Secrets management. Store API keys, tokens, and credentials in ConfigSync’s encrypted secret store instead of in plaintext dotfiles.

Package tracking. ConfigSync tracks your installed Homebrew formulae, npm global packages, and more. On a new machine, configsync pull --install installs everything.

Your ~/dotfiles directory served you well. ConfigSync takes over from here with encryption, cloud sync, and no symlinks to worry about.

Ready to try ConfigSync?

Sync your entire dev environment across machines in minutes. Free forever for up to 3 devices.