Set-and-forget dotfile sync for macOS and Linux.
Decide what's managed from any machine; every machine converges automatically.
Never silently overwrites a local change.
Documentation · Quick start · Download
$ dotsync init git@github.com:you/dotfiles.git
$ dotsync add ~/.config/fish/config.fish -d "Fish shell configuration"
managing ~/.config/fish/config.fish as 'fish/config.fish'
sent ~/.config/fish/config.fish
dotsync: 1 sent — pushed 1c049fe
$ dotsync status
dotsync on laptop: git@github.com:you/dotfiles.git (main @ 1c049fe)
last sync: 2026-09-21T11:16:09+05:30 (ok)
automatic sync: launchd agent loaded
SOURCE TARGET STATUS DESCRIPTION
fish/config.fish ~/.config/fish/config.fish ok Fish shell configuration
gitconfig ~/.gitconfig CONFLICT Git identity and aliases
nvim ~/.config/nvim/ ok Neovim
conflicts (neither version has been changed):
~/.gitconfig since 2026-09-21T11:16:09+05:30
inspect: dotsync diff <path> settle: dotsync resolve <path> --keep local|remote
(to merge by hand, edit the local file, then --keep local)That's the whole workflow. From then on a background agent keeps every machine in sync. You only hear from dotsync when two machines changed the same file and it needs you to pick a version.
Most dotfile managers are deployment tools: you edit a repo, then run a command on each machine. dotsync is a synchronizer: edit the real file wherever you are, and it shows up everywhere else.
- Automatic, both ways. Edit
~/.gitconfigon any machine and it propagates. Add or remove managed files from any machine too. - Safe by default. Local files are backed up before they are replaced or deleted. If two machines change the same file, both versions are kept and you get a conflict instead of a silent winner.
- Secrets stay home. SSH keys, cloud credentials, tokens in shell rc files and similar things are refused before they reach the remote.
- Offline-tolerant. Machines that were away for a month catch up correctly when they reconnect.
- Few moving parts. One static binary plus
git, and a private git repo you already know how to host. No daemon, database, server or account. - Light on your battery. A sync with nothing to do runs two git processes and writes nothing but a timestamp. There's no randomized scheduling and no surprise background work.
- Portable. Targets are written as
~/…or$XDG_CONFIG_HOME/…. Per-OS entries and per-machine exclusions keep machine-specific settings out of the shared config.
brew install pungoyal/tap/dotsync # Homebrew (macOS, Linux)
curl -fsSL https://raw.githubusercontent.com/pungoyal/dotsync/main/install.sh | sh # or the install scriptOn Ubuntu and Debian, install from the signed APT repository:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://pungoyal.github.io/dotsync/apt/dotsync.asc | sudo tee /etc/apt/keyrings/dotsync.asc >/dev/null
curl -fsSL https://pungoyal.github.io/dotsync/apt/dotsync.sources | sudo tee /etc/apt/sources.list.d/dotsync.sources >/dev/null
sudo apt update && sudo apt install dotsyncHomebrew and apt keep dotsync up to date like any other package.
The install script downloads the right binary for your OS and CPU and checks its SHA-256 checksum before installing it to ~/.local/bin. Later, dotsync update upgrades in place with the same checks. If the GitHub CLI is installed, it also verifies the build provenance attestation. See verifying releases.
Other ways to install
Prebuilt binaries and .deb packages: download from the releases page. Builds exist for macOS and Linux, on amd64 and arm64.
With Go 1.23+:
go install github.com/pungoyal/dotsync/cmd/dotsync@latestFrom source:
git clone https://github.com/pungoyal/dotsync && cd dotsync && make build # → bin/dotsync-
Create an empty private repository on GitHub, GitLab or anywhere else you can reach with git. Make sure
git cloneworks for it without a password prompt (an SSH key, or a credential helper). -
On your first machine:
dotsync init git@github.com:you/dotfiles.git dotsync add ~/.gitconfig ~/.config/fish/config.fish ~/.config/nvim
-
On every other machine, run the same
init. Managed files show up. If a local file already existed and differed, it is backed up first and then replaced with the shared version. -
That's it. Edit files as you normally would; they sync every 5 minutes. Run
dotsync doctorto check the setup, anddotsync statusany time to see what's going on.
Follow the quick start for a guided tour.
A private git repository holds a manifest: which files are managed, where they go, and what they are. It also holds their content. Every machine keeps a private record of the version it last agreed on with the remote (the base). Each sync compares three versions of every file:
| local vs. base | remote vs. base | what dotsync does |
|---|---|---|
| same | same | nothing |
| same | changed | back up the local file, install the remote version |
| changed | same | push the local version |
| changed | changed | conflict: touch nothing, tell you |
There are no git merges, rebases or clever heuristics. The full design is in How sync works.
| Quick start | Two machines in sync in five minutes |
| Guides | Managing files, conflicts, secrets, per-machine differences, migration |
| How sync works | The model and its safety guarantees |
| Reference | Commands, manifest, configuration, files, secret rules |
| dotsync | chezmoi | yadm | GNU Stow | Mackup | mise dotfiles | |
|---|---|---|---|---|---|---|
| You edit | the real file | the source, or the file then chezmoi re-add |
the real file | the real file, through its symlink | the real file | the real file, or the source for copied and templated files |
| Other machines get changes | automatically | when you run chezmoi update |
when you run yadm pull |
when you pull the directory | when you run mackup restore |
automatically with the history watcher and history.sync = "sync", otherwise when you run mise dot sync |
| Same file changed on two machines | per-file conflict: both kept, you choose | git merge conflict in the source; asks before overwriting a file changed since the last apply | git merge conflict | git merge conflict, if the directory is a git repository | whatever the storage provider does | per-file conflict, but sync pauses for every tracked file until you choose |
| Secrets | held back before upload | templates that read password managers; encryption | encryption | not handled | not handled | encryption; credential files skipped by name |
| Differences per machine | per-OS entries, per-machine exclusions | templates | alternate files, templates | separate packages | not handled | templates, per-OS and per-profile variants |
dotsync deliberately does not do templating. If you need one file to differ per machine in complicated ways, chezmoi is excellent. dotsync is for people who want their files to simply be the same everywhere, with no ceremony.
Contributions are welcome. Please read CONTRIBUTING.md first. Security issues go through SECURITY.md, not public issues.