How I sync my config files with Stow

A simple system to keep chaos at bay

August 27, 2022

An organisational nightmare

I have one machine for work, one machine for personal stuff and a bunch of servers for projects and school work. As I hop in and out of these separate computing systems, it gets pretty difficult to synchronise all my config files, settings, scripts and shortcuts.

DallE2 art with prompt: ‘Keeping things organized across multiple machines, digital art’

1As this is a common problem that plagues many programmers, it is unsurprising that there is a clever piece of software written to solve this problem - Stow. Stow is a symlink manager that when coupled with any version control software (ie. git) can create a simple and effective config sync system. I have used such a system for the last couple of months and is something I can no longer live without.

I find myself bringing up Stow pretty often in conversations so I wanted to take @drob’s advice. However, as there are many excellent blogs that already do a great job explaining what Stow is, I think I can’t add much value to that conversation. Instead, I’m going to shift my energy toward creating a straightforward how-to recipe.

The Big Picture

Here is the big picture of how a Stow-enabled config synchronisation system is set up.

  1. You will need a dotfiles version-controlled repository. The simplest approach here would be to create a Github repository

  2. In dotfiles, you will create separate folders for each application’s config file you wish to keep in sync. What you name these folders is totally up to you, but conventionally most people name the folder after the application

For example, a simple dotfiles repo might look like this.

├── aliases
├── kitty
└── nvim

Here, I intend to sync my shell aliases, terminal configs (Kitty) and editor configs (NeoVim), so I create a separate folder for each.

  1. Within each folder, you can create the config files that we want to be kept in-sync

  2. Using Stow, you can then create a symlink of these config files which would be placed in the right locations on your file system for the respective applications to read from

  3. Once this is set up, the day-to-day usage of this system is incredibly simple. Any time you make make edits to your config files on 1 machine, you simply need to commit and push the changes made in your dotfiles repo. Your config files are symlink-ed to the files in your dotfiles repo, and any edit you make will be updated. Next time you hop into a different machine, just pull down the latest changes in the dotfiles repo and all your configs will be updated

Steps 3 and 4 are the tricky bits and I provide a more detailed example of them below.

Syncing a config file for the 1st time

Here is an example scenario. I have 2 machines (A and B), and I want to sync the configurations for the terminal application, e.g. the Kitty terminal. To configure this terminal, you would edit a config file kitty.conf whose default location is ~/.config/kitty/kitty.conf. Here is what you would do:

Yes, I see the irony in using Kitty because it is a GPU-accelerated application whose primary function is to print out text…

  1. We start from machine A. Firstly, you will need to delete the existing kitty.conf file

  2. In your dotfiles repo, within the kitty folder, create a new kitty.conf file but make sure this file is in the same folder structure of the default config location. I.e. your new config file should sit in the dotfiles repo like this

├── aliases
├── kitty
   └── .config
       └── kitty
           └── kitty.conf
└── nvim
  1. Fill up kitty.conf with your desired settings

  2. Navigate back up to the dotfiles repo and run stow kitty. This command will create a symlink of the contents of the kitty folder, which will create a kitty.conf in the ~/.config/kitty/kitty.conf location

  3. We are done setting up on Machine A. Commit and push the changes to your dotfiles repo

  4. Finally, log into Machine B. Pull down the changes and because we have not run stow in this machine, you will need to run stow kitty here too to create the symlinks.

Stow is something you only need to run the 1st time you add a config file. You do not have to run stow for any subsequent edits.


This config sync system is pretty sweet but it is not without some limitations. Here is a couple for you to be aware of.

Stowing too many config files can also get out of hand pretty quickly. You probably want to consider which applications you are genuinely using often enough across multiple machines, just so you avoid creating obsolete symlinks.

Additionally, there are some situations where you do not want config files synced. For example, I do not use this system to sync my shell configs because my shell configs might contain sensitive environment variables or have settings unique to the type of hardware the software is running on.


─ Session info ───────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.3.1 (2023-06-16)
 os       macOS Ventura 13.5
 system   x86_64, darwin20
 ui       X11
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Asia/Singapore
 date     2023-08-10
 pandoc   3.1.6 @ /usr/local/bin/ (via rmarkdown)
 quarto   1.3.433

─ Packages ───────────────────────────────────────────────────────────────────
 package     * version date (UTC) lib source
 sessioninfo * 1.2.2   2021-12-06 [1] CRAN (R 4.3.0)

 [1] /Users/ddanieltan/Code/
 [2] /Users/ddanieltan/Library/Caches/org.R-project.R/R/renv/sandbox/R-4.3/x86_64-apple-darwin20/84ba8b13

Study hard what interests you the most in the most undisciplined, irreverent and original manner possible – Richard Feynman



BibTeX citation:
  author = {Tan, Daniel},
  title = {How {I} Sync My Config Files with {Stow}},
  date = {2022-08-27},
  url = {},
  langid = {en}
For attribution, please cite this work as:
Tan, Daniel. 2022. “How I Sync My Config Files with Stow.” August 27, 2022.