How It Works
Mental model, data flow, and internal structure of Devsync.
Devsync is built around a single idea: your local files are always the source of truth. The repository is a sync artifact, not the canonical version of your config.
This guide covers the mental model, data flow, and internal structure.
The Mental Model
Section titled “The Mental Model”Most dotfile tools treat the repository as the canonical state. You edit files through the tool, and the tool writes to both the repository and your local filesystem.
Devsync inverts this. You edit ~/.zshrc directly in your editor — no special command needed. When you’re ready to sync, you run devsync push, which reads your current local files and mirrors them into the repository.
Your editor → local files → devsync push → sync repository → git push → remote ↓other machine ← devsync pull ← sync repository ← git pull ← remoteThe benefit is that your editing workflow stays completely natural. The trade-off is that the repository state reflects the last push, not the current state of your local files.
Data Flow
Section titled “Data Flow”When you run devsync push, devsync:
- Loads
manifest.jsonand determines the active profile - Walks the local file tree for each tracked path
- Compares local files with the existing artifacts in the sync directory
- Encrypts any
secret-mode files using age before writing - Writes the mirrored artifacts to the sync directory
- Reports what changed
When you run devsync pull, devsync:
- Loads
manifest.jsonand determines the active profile - Reads the artifacts present in the sync directory
- Decrypts any
secretartifacts using your age private key - Writes files to their local paths, creating parent directories as needed
- Applies file permissions
- Reports what changed
Directory Structure
Section titled “Directory Structure”All devsync state lives under ~/.config/devsync/:
Directory~/.config/devsync/
Directorysync/ Git repository (synced files stored here)
Directory.git/
- …
- manifest.json Config and tracking registry
Directorydefault/ Artifacts for the default (global) profile
- .gitconfig Mirrored from ~/.gitconfig
Directory.config/
Directorynvim/ Mirrored from ~/.config/nvim
- …
Directorywork/ Artifacts for the “work” profile
- …
Directoryage/
- keys.txt Age private key (for decrypting secrets)
- settings.json Global settings (active profile, etc.)
manifest.json
Section titled “manifest.json”The manifest is the central registry. Every tracked path has an entry describing its source path, sync mode, and optional profile assignments:
{ "entries": [ { "localPath": ".gitconfig", "mode": "normal", "profiles": [] }, { "localPath": ".ssh/config", "mode": "secret", "profiles": [] }, { "localPath": { "default": ".config/nvim", "win": "AppData/Local/nvim" }, "mode": "normal", "profiles": ["linux", "mac"] } ]}Paths in localPath are relative to your home directory (~).
How This Differs from stow and chezmoi
Section titled “How This Differs from stow and chezmoi”| devsync | chezmoi | stow | |
|---|---|---|---|
| Source of truth | Local files | Repository | Repository |
| Edit workflow | Open file directly | chezmoi edit | Edit in repo |
| Home directory | Unmodified | Unmodified | Symlinks |
| Template support | No | Yes | No |
| Per-machine content | Profiles / platform paths | Templates | Overlays |
Devsync prioritizes keeping your editing workflow natural. If you already have a comfortable setup and just want it replicated across machines, devsync gets out of your way.