How do you manage your dotfiles across multiple and/or new developer machines?

lostintangent profile image Jonathan Carter ・1 min read

Hey All! I’m curious to hear the gritty details about how you synchronize your dotfiles (e.g. .bash_profile, .gitconfig) between multiple dev machines (e.g. your desktop and laptop) and/or to help simplify setting up new machines (e.g. a shiny new MacBook 💻).

Do you store them in a public or private GitHub repo? DropBox? Somewhere else? Once cloned to the target machine, do you install the dotfiles...

  1. Manually (e.g. moving files around, running a series of commands)
  2. By running a custom shell script stored alongside your config files
  3. Using an automation tool, such as Ansible or Puppet
  4. Using a “dotfile manager” such as GNU Stow, Dotbot or Homesick

If you’ve already written a blog post about your setup, feel free to link it. Otherwise, I’d love to hear what has been working well for you, and any pro tips you can share. There are a ton of options here, and so I’m very interested to learn more about what folks are actually doing in practice 🙌

Posted on Apr 20 '19 by:

lostintangent profile

Jonathan Carter


I build developer tools and services at Microsoft (currently VS Online, Live Share, IntelliCode, and Playwright, previously CodePush, IE Dev Tools, Visual Studio, Azure).


markdown guide

For those that are interested, I found an old HackerNews thread, and Reddit Survey that have a ton of valuable perspectives. This article also provides a really nice explanation of the general practice that many people seem to be taking: store dotfiles in GitHub, and then install them via a simple script that symlinks files and runs any additional init logic.

Also, I’m porting some helpful links that folks have shared on Twitter:

  1. Managing Dotfiles with Stow
  2. Managing your dotfiles
  3. Dotfiles Home Configuration

I manage mine, as I’m sure many do, via a Github repo — as well as my vimrc. They both include make based installers for easy installation, as well as (very old) Dockerfiles for quick mucking container.

The dotfiles repo loads a .localrc to include things I don’t wish to share. Mostly very work specific aliases and functions.

Admittedly, I don’t push nearly often enough, nor do I clean up the files within with any kind of diligence.


Very cool! I really like the “.localrc” idea. That seems like a great solution for keeping a public dotfiles repo for most of your settings, while being able to keep some things private 👍


I put all my dotfiles that I want to share in a public repo that I host on Github

GitHub logo coreyja / dotfiles

My dotfile Repo

Coreyja's dotfiles

Screenshot of my shell prompt


Warning: If you want to give these dotfiles a try, you should first fork this repository, review the code, and remove things you don’t want or need. Don’t blindly use my settings unless you know what that entails. Use at your own risk!

Using Git and the bootstrap script

You can clone the repository wherever you want. (I like to keep it in ~/Projects/dotfiles, with ~/dotfiles as a symlink.) The bootstrapper script will pull in the latest version and copy the files to your home folder.

git clone https://github.com/mathiasbynens/dotfiles.git && cd dotfiles && source bootstrap.sh

To update, cd into your local dotfiles repository and then:

source bootstrap.sh

Alternatively, to update while avoiding the confirmation prompt:

set -- -f; source bootstrap.sh

Git-free install

To install these dotfiles without Git:

cd; curl -#L https://github.com/mathiasbynens/dotfiles/tarball/master | tar -xzv --strip-components 1 --exclude={README.md,bootstrap.sh,.osx,LICENSE-MIT.txt}

To update later on, just run…

I do something that I think is somewhat unconventional but I really like it! And that is keep my actual home directory under version control. To accomplish this my .gitignore starts with * so that it ignores everything. Then I go in an specifically include files like !file.txt.

This means I don't have to deal with any symlinks or scripts when I pull updates. I also can edit the actual 'live' files and then commit those same files, which makes sharing between machines painless! I've written a few blog posts about my dotfiles!

This second one discusses some recent change to my dotfiles around Homebrew 2


It definitely seems like many of the “dot file managers” are simply working around the fact that folks don’t want to make their home directory a Git repo. Have you run into any downsides with this solution? It certainly seems really simple.


Not any huge ones, but there are definitely some interesting side effects.

One if that I am always in a git repo now basically, so my bash indicator of if I'm in a git branch is slightly less meaningful
Two some tools (ex: ripgrep) use your .gitignore file as a generic ignore file when searching, so this needs to be worked around. I accomplish this my using something like rg --no-ignore --glob "!.git/*". I find I don't actually run into this too often, as usually I am running rg from within a different project directory, where it's local .gitignore is used so this isn't an issue.

Besides that everything works as expected! I've been doing it for a few years now and really enjoy the setup!


I typically keep them all in the GitHub, luckily none of mine have any secrets or anything like that.


After you clone the repo on to your machine, how to you install them (e.g. symlinking files, etc.)? Do you have something like an “install.sh” script in the repo that you run?


That would be clutch! I typically just copy and paste if there are any updates, many changes outside of the base set ups are specific to the laptop for work vs personal !

Here’s my very personalize Makefile for installing which perhaps could be adapted.


Which, when looking over just now for the first in quite a while, needs some clean up.

Hmmmm I like this enough that I might do it too. Right now I'm symlinking everything in a bash script which works well, but the uninstall would have to be manual at the moment. I like that make would kind of supervise all of that.


I store everything in an org file which I can choose to encrypt using the :crypt: tag. This file can live anywhere(GitHub, Dropbox, drive, etc etc). The dotfiles are stored in source blocks from which I'll tangle to the relevant place in the file system. This approach works really well if you are a heavy emacsen user.


As a non-Emacs user (apologies!), I’m not too familiar with org files. Any pointers that could help me understand this solution a bit better? I’m really intrigued 🤗


Just wanted to say thank you for the discussion topic. I am storing mine in Dropbox at the moment and I’m very new to bash and using dotfiles and etc. I have read many of the things here and I will try to refactor. I have been using bash’s source to include scripts (functions) and settings from a folder in Dropbox. I simply didn’t know of other ways and it’s great to see them now.

After reading several things here I may create a git repo and then I will likely just create symlinks for what I need (as well as a script to generate those symlinks on a fresh install).


I currently store them in a secret gist, but I'm creating an install command, and storing it in a secret GitHub repo. It will basically download everything I need and setup all the files to keep my aliases, ZSH themes, Spotify theme (using Spicetify), etc


Out of curiosity: why are you using a secret Gist? Are you storing secrets in there, that you wouldn’t want others to see?

Also, have you considered using a “dot file manager” such as YADM or Homeshick, as opposed to scripting your own solution?


I don't have any secrets within the files, not sure why I keep it private... Better safe than sorry I guess?

I didn't know they existed, actually! I discovered with your post. I might still finish my own as it will also install all the softwares I need and apply themes/plugins (For example, it would download VSCode and apply my themes and plugins). I might consider using the dot file managers for the dot files and keeping my "install script" just for the things it can't do.

One World Scholarship Programme 2019/2020
Application Deadline: July 31th, 2019.

The One World Scholarship Programme is a partial scholarship aimed at students from Africa, Asia and Latin America who have come to Austria on their own initiative, in order to complete their education. Prospective awardees are required to focus on questions related to development in their studies and research.

Formal requirements and conditions:
nationality of a non-European developing country (country list)
admission to a Master or PhD programme at a university or university of applied sciences in Salzburg or Tyrol (Uni Salzburg, Uni Innsbruck, FH Salzburg, MCI, FH Kufstein)
for PhD students: approved disposition
age limit: Master studies max. 30 years (mothers: 35 years), PhD studies max. 35 years (mothers: 40 years) at the time of application
residence permit “student”

READ MORE scholarshiponline.website/2019/07/...


I keep my dotfiles in a Github repository, alongside with a list of things to set up manually. There is a script I copied from somebody's dotfiles repo that does the symlinks. If I update a dotfile on one machine, I just pull from the other. I also have a .bash_profile_priv file that I load from .bash_profile but do not commit, so that I can set there env variables and such that only make sense for one machine or are secrets.

I also keep an install script that installs various packages and apps via brew, and detailed instructions how to configure manually the system and certain apps to my liking.

Spending time on this repo paid off big time. I have re-installed the system more than 5 times now using this repo and I can't imagine not having it. I don't have to think much during the process, I just follow my list :).


Ohhhh, symlinks 🤦‍♀️ Of course!
Thanks for sharing. I also use github to manage my dotfiles and I've been thinking about how I wanted to manage syncing them without making my home folder a git repo. I was halfway through setting up some bash scripts with rsync, but symlinks are so much less effort and will work better.


I just keep a dotfiles repo on GitHub and sync it / set it up with Ansible. It's nice because the same Ansible role works in WSL on Windows and a native Linux box.


Is the Ansible role code in the same dotfiles repo? That way you can clone it and run Ansible on it?


Nope, right now that specific Ansible role isn't open source since it has very personalized information in it specific to my development environment but if it were to be released, it would be in its own separate repo as a dedicated dotfiles Ansible role.

Then you would configure the role to set up your dotfiles. At some point I may refactor it all to be a general role, but it's not a super high priority at the moment. It mainly just clones my dotfiles repo and sets up symlinks.

Currently I have that functionality along with some other things all smashed together in a custom role, which happens to do other things besides dotfiles but is related to setting up a new WSL / Linux development environment.


I feel ashamed to say that I only care about my ohmyzsh dir and .zshrc file and store them on Dropbox (because of native Linux app) and symlink them whenever I start a new computer in order to have the same plugins and config across my laptops and workstations.

But I'm gonna check those solutions because that seems neat.


A slight twist on the tried-and-true git-plus-symlinks: On the machines where I su to root, I wanted the same setup as for my normal user. I figured symlinking to the normal user's files was a bad idea and the other way around, I dunno, running git as root also seemed like a bad idea.

So I created a passwordless dotfile user who owns the files. Only root can switch to the user and the user itself has zero privileges. It's a bit more cumbersome (especially when making changes) but it has worked really well.


As mentioned by many others, it's pretty handy to simply store everything in a Git repo. It's easy to keep track of changes and it's easy to share things with your machines and also with others.
I also wrote about my setup to make it easy to keep my machines up to date and setup new ones.


Ah nice! Thanks so much for sharing this. I searched past #discuss posts and totally missed this 🤗


No problem, I've got it permanently on my reading list so I can refer back to it. Post back here if you find an option that works well. I haven't had a chance to try any yet.


Hey there! As most folks are saying I'm the same way, I have a Github repo :)

It makes life a lot easier to just do incremental changes, and i've actually rolled back some stuff i didn't like before.