GuideMay 5, 20266 min read

Migrating from Dotbot to ConfigSync

Dotbot bootstraps your dotfiles once. ConfigSync keeps them synced forever. Here's how to make the switch.

How Dotbot Works

Dotbot is a lightweight dotfile bootstrapper that lives as a git submodule inside your dotfiles repo. You define your setup in an install.conf.yaml file with three types of directives: symlink creation, shell commands, and directory cleanup.

install.conf.yaml

- defaults:

link:

relink: true

create: true

- link:

~/.zshrc: zsh/zshrc

~/.gitconfig: git/gitconfig

~/.config/nvim: nvim

~/.ssh/config: ssh/config

- shell:

- [brew bundle --file=Brewfile, Installing Homebrew packages]

- [npm install -g typescript, Installing global npm packages]

- clean: ['~']

Clone the repo, run ./install, and your machine is set up. It is simple, it is reliable, and it has served the dotfile community well for years.

Why Switch from Dotbot

Dotbot solves the bootstrap problem — getting a new machine from zero to configured. But it stops there. Once your machine is set up, Dotbot has nothing more to offer.

  • No ongoing sync — change a config on your laptop and your desktop does not know about it
  • No encryption — your dotfiles repo contains everything in plaintext, including any secrets
  • No package tracking — the shell commands in your YAML are static; they do not track what you install later
  • Symlink maintenance — if you reorganize your repo, you need to update every path in the YAML
Dotbot is a bootstrapper, not a sync engine. If you work across multiple machines or care about encrypting secrets, you have outgrown what Dotbot can do.

Mapping Dotbot Directives to ConfigSync

Every directive in your install.conf.yaml has a ConfigSync equivalent. Here is how they map:

Dotbot DirectiveConfigSync EquivalentNotes
link: ~/.zshrc: zsh/zshrcconfigsync add module zshModule captures all zsh files automatically
link: ~/.gitconfig: git/gitconfigconfigsync add module gitModule captures gitconfig and global gitignore
link: ~/.ssh/config: ssh/configconfigsync add module sshSSH module encrypts private keys
link: ~/.config/custom: customconfigsync add config ~/.config/customFor files without a module
shell: brew bundleconfigsync scanAuto-detects and captures package lists
clean: [~]Not neededConfigSync copies files, not symlinks

Step-by-Step Migration

1. Read your install.conf.yaml

Open your Dotbot config and make a list of every link: entry. These are the files ConfigSync needs to capture. Group them into files that map to modules (ssh, git, zsh, neovim, vscode) and files that need to be added individually.

2. Add modules for standard tools

Terminal

configsync add module ssh

configsync add module git

configsync add module zsh

configsync add module neovim

configsync add module vscode

Modules are smarter than symlink entries — they know which files belong to each tool and handle platform differences automatically.

3. Add remaining config files individually

For any link: entries that do not correspond to a module:

Terminal

configsync add config ~/.config/starship.toml

configsync add config ~/.config/alacritty/alacritty.yml

configsync add config ~/.tmux.conf

4. Convert shell commands to hooks or bootstrap scripts

Dotbot's shell: directives run commands during bootstrap. In ConfigSync, you have two options:

~/.configsync/bootstrap.sh

#!/bin/bash

# One-time setup commands (replaces Dotbot shell directives)

brew bundle --file=~/.configsync/Brewfile

npm install -g typescript eslint

Alternatively, use post-pull hooks for commands that should run every time you pull on a new machine.

5. Remove Dotbot from your dotfiles repo

Terminal

# Remove the git submodule

git submodule deinit dotbot

git rm dotbot

rm -rf .git/modules/dotbot

# Remove the config

rm install.conf.yaml install

6. Push your configuration

Terminal

configsync push

Everything is now encrypted and synced to the cloud. On a new machine, configsync pull replaces the old git clone && ./install workflow.

What You Gain

After migrating, your dotfile management goes from "run a script once" to "always in sync":

  • Continuous sync — changes propagate across machines automatically with watch mode
  • Encrypted secrets — SSH keys and API tokens are AES-256-GCM encrypted, not sitting in a git repo
  • Package tracking — ConfigSync captures your installed packages dynamically, not as a static shell command
  • No symlink management — ConfigSync copies files directly, so there are no broken symlinks to debug
  • Snapshot rollback — made a bad config change? Roll back to any previous snapshot

Dotbot got your dotfiles off the ground. ConfigSync takes them to the next level.

Ready to try ConfigSync?

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