A lightweight CLI tool for syncing config files across machines using cloud storage providers.
dotsync helps you keep your developer config files (dotfiles, tool configs, etc.) synchronized across multiple machines without the complexity of version control or specialized sync services. It works by moving your config files to cloud storage and creating symlinks at their original locations, letting your existing cloud provider handle the synchronization.
I have several tools that I use on a daily basis for software development and most of them have local only configs. Because I work on 2 machines, I want the configs of those tools to stay in sync. For a while I was doing it manually, using Google Drive as backend and creating symlinks for all the config files I needed. Eventually it became tedious and repetitive, and so I made dotsync to streamline the process.
- Multi-provider support - Works with any cloud storage that you can mount locally
- Auto-detection - Automatically finds your cloud storage locations if using Google Drive, Dropbox, or iCloud Drive
- Symlink management - Seamlessly manages symlinks between local and cloud storage
- Entry-based tracking - Groups related files together (e.g., all OpenCode configs)
- Cross-machine sync - Set up once, sync everywhere
- Safe operations - Automatic backups before destructive operations
- Status tracking - View sync status of all tracked files
- One of the supported cloud storage providers (Google Drive, Dropbox, or iCloud Drive) installed and syncing
- For building from source: Go 1.25 or later
macOS & Linux:
curl -fsSL https://raw.githubusercontent.com/wtfzambo/dotsync/main/scripts/install.sh | bashWindows (PowerShell):
irm https://raw.githubusercontent.com/wtfzambo/dotsync/main/scripts/install.ps1 | iexDownload the latest release for your platform from the releases page and extract it to a directory in your PATH.
git clone https://github.com/wtfzambo/dotsync.git
cd dotsync
task buildThe binary will be available at ./bin/dotsync.
go install github.com/wtfzambo/dotsync/cmd/dotsync@latestdotsync --versionChoose your cloud storage provider and initialize:
# For Google Drive
dotsync init gdrive
# For Dropbox
dotsync init dropbox
# For iCloud Drive (macOS only)
dotsync init icloud
# Or specify a custom path
dotsync init --path ~/my-cloud-folderdotsync will auto-detect your cloud storage location and create a dotsync folder inside it to store your synced files.
Add config files or directories you want to sync:
# Add a config file
dotsync add ~/.config/opencode/config.json
# Add a dotfile
dotsync add ~/.zshrc
# Add with a custom entry name
dotsync add ~/.aws/credentials --name aws-configEach file is moved to cloud storage and replaced with a symlink. Related files are grouped into "entries" (e.g., all files under ~/.config/opencode/ become the "opencode" entry).
View all tracked files and their sync status:
# List all entries
dotsync list
# Show detailed file information
dotsync list --detailsOn another machine with the same cloud storage account:
# Initialize with the same provider
dotsync init gdrive
# Create symlinks for all tracked files
dotsync link
# Or link a specific entry
dotsync link opencodedotsync will create symlinks pointing to the cloud-synced files. If local files exist, you'll be prompted to back them up, skip, or abort.
- macOS:
~/Library/CloudStorage/GoogleDrive-*/My Drive - Linux:
⚠️ ~/Google Driveor~/google-drive - Windows:
G:\My Drive - Auto-detection: Yes
Warning
Google Drive doesn't support Linux natively. GNOME has a built-in Google integration that does mount a Google Drive folder locally, but browsing it through the terminal is impossible due to the fact that files and directories are stored with their IDs rather than their names, which likely will hinder the functionality of dotsync.
If you encounter this issue, one way (admittedly tedious) to circumvent it is to use something like google-drive-ocamlfuse.
- macOS:
~/Library/CloudStorage/Dropboxor~/Dropbox - Linux:
~/Dropbox - Windows:
~\Dropbox - Auto-detection: Yes
- macOS:
~/Library/Mobile Documents/com~apple~CloudDocs - Auto-detection: Yes
If auto-detection fails, you can specify the path manually using dotsync init --path <your-path>.
| Command | Description | Examples |
|---|---|---|
init <provider> |
Initialize dotsync with a cloud storage provider | dotsync init gdrivedotsync init --path ~/my-cloud |
add <path> |
Add a file to be synced | dotsync add ~/.zshrcdotsync add ~/.config/test/config.json |
list |
List all tracked entries and their status | dotsync listdotsync list --details |
link [entry] |
Create symlinks for tracked files | dotsync linkdotsync link opencodedotsync link --backup |
unlink [entry] |
Remove symlinks and restore files locally | dotsync unlinkdotsync unlink opencode |
Initializes dotsync with a cloud storage provider.
Flags:
-p, --path <path>- Explicitly specify the storage path (skips auto-detection)
Example:
dotsync init gdriveAdds a file to be tracked and synced. The file is moved to cloud storage and replaced with a symlink.
Flags:
-n, --name <name>- Specify a custom entry name (otherwise inferred from path)
Example:
dotsync add ~/.config/opencode/config.json
dotsync add ~/.aws/credentials --name aws-configLists all tracked entries and their sync status on this machine.
Flags:
-d, --details- Show detailed file list for each entry
Example:
dotsync list --detailsCreates symlinks for tracked files. Use this on a new machine to set up symlinks pointing to cloud-synced files.
Flags:
-b, --backup- Automatically backup existing files without prompting
Example:
dotsync link # Link all entries
dotsync link opencode # Link only the "opencode" entry
dotsync link --backup # Auto-backup conflictsRemoves symlinks and copies files from cloud storage back to their original locations. The files remain tracked and can be re-linked later.
Example:
dotsync unlink # Unlink all entries
dotsync unlink opencode # Unlink only the "opencode" entrydotsync uses a simple approach to sync files across machines:
-
File Movement: When you add a file, dotsync moves it from your local filesystem to a
dotsyncfolder in your cloud storage. -
Symlink Creation: A symlink is created at the original file location, pointing to the cloud storage location.
-
Cloud Sync: Your cloud storage provider (Google Drive, Dropbox, iCloud) handles the actual synchronization across machines.
-
Manifest Tracking: A manifest file (
.dotsync.json) in cloud storage tracks all files and their locations. -
Multi-Machine Setup: On another machine,
dotsync linkreads the manifest and creates the appropriate symlinks.
<cloud-storage>/
└── dotsync/
├── .dotsync.json # Manifest file
├── opencode/ # Entry name
│ └── config/
│ └── config.json # Actual file
└── zsh/ # Another entry
└── .zshrc
dotsync stores its local configuration at ~/.config/dotsync/config.json. This file contains:
- The cloud storage path
- Local settings (if any)
Windows 10/11 requires Developer Mode or Administrator privileges to create symlinks. If you encounter "access denied" errors when running dotsync add or dotsync link:
-
Enable Developer Mode (recommended):
- Open Settings > Privacy & Security > For developers
- Turn on "Developer Mode"
- This allows any user to create symlinks without elevation
-
Run as Administrator (alternative):
- Open PowerShell or Command Prompt as Administrator
- Run dotsync commands from the elevated shell
Without either of these, dotsync cannot create the symlinks needed for file synchronization.
macOS 14+ does NOT support symlinks for plist files in ~/Library/Preferences/. dotsync will reject these files with an error message. For syncing plist files, use Mackup with Copy mode instead.
dotsync will warn you if you try to add files outside your home directory. Symlinks may not work correctly if the absolute paths differ across machines.
You can only add files that currently exist on your filesystem. dotsync cannot add files that don't exist yet.
All commands require your cloud storage to be mounted and accessible. If you see "storage unavailable" errors, check that your cloud storage is running and synced.
task build # Optimized build
task dev # Fast build without optimizationstask test # Run all tests
task test:cover # Generate coverage reporttask clean # Remove build artifacts
task tidy # Tidy Go modules
task lint # Run linters (requires golangci-lint)
task install # Install to GOPATH/binContributions are welcome! Please feel free to submit issues or pull requests.
Built with:
- Cobra - CLI framework
- Go standard library