A cross-platform dotfiles manager for macOS and Linux. Sync configs across machines with profile-based organization, automatic discovery, and remote deployment.
- Cross-platform - Separate paths per platform (macOS/Linux)
- Profile-based - Organize configs into minimal, dev, and full profiles
- Interactive CLI - Menu-driven interface with prompts
- Remote deployment - Deploy to remote machines via SSH + rsync
- Preferences sync - Backup and restore system preferences (macOS defaults, Linux gsettings)
- Auto-discovery - Scan for 210+ known config file patterns
- Brewfile sync - Generate Brewfile from installed Homebrew packages
- Conflict resolution - Detect and handle conflicts during deployment
Requires Bun.
git clone https://github.com/yourusername/dots.git
cd dots
bun installAdd to your PATH or create an alias:
alias dots='bun /path/to/dots/src/index.ts'# Interactive menu
dots
# Initialize dots configuration
dots init
# Backup configs from system to repo
dots backup
# Deploy configs to local machine
dots deploy
# Deploy to a remote machine
dots remoteSet up your dotfiles repository for the first time:
- Choose repository location (default:
~/dotfiles) - Configure Brewfile sync preference
- Initialize git repository
- Optionally push to GitHub
dots init # Interactive setup wizard
dots init -f # Force reinitializeBackup configuration files from your system to the repository:
- Check for manifest (prompts init if missing)
- Optionally discover new configs to track
- Backup all tracked configs to repo
- Optionally backup system preferences
- Git commit and push
dots backup # Interactive backup
dots backup -a # Non-interactive: sync all, commit, push
dots backup -n # Dry run - preview changes
dots backup -y # Auto-confirm promptsModes:
- Interactive (default): Prompts for discovery, prefs backup, commit message
- Non-interactive (
-a): Syncs all tracked configs, auto-commits with default message, pushes
Deploy configs from repository to local machine:
- Git checks (warn uncommitted changes, offer to pull)
- Select deployment profile
- Select configs to deploy (shows diff preview)
- Select packages to install from Brewfile (macOS)
- Select preference categories to apply
- Resolve any conflicts
- Execute: packages → configs → prefs
- SSH key setup guidance
- Post-setup instructions
dots deploy # Interactive deployment
dots deploy -p minimal # Deploy specific profile
dots deploy -f # Force deploy, skip confirmations
dots deploy -n # Dry run - preview changesConflict Resolution: When local files differ from repo versions:
- Overwrite - Replace local with repo version
- Keep - Skip this config
- Backup then overwrite - Save local as
.backup, then deploy
Deploy configs to a remote machine via SSH:
- Enter SSH credentials (host, username)
- Test connection and detect remote platform
- Select deployment profile
- Select configs to deploy
- Select packages to install (if macOS remote)
- Select preferences to apply
- Execute deployment via rsync
- Post-setup instructions
dots remote # Interactive SSH deployment
dots remote -p dev # Deploy dev profile to remote
dots remote -n # Dry run - preview changesFeatures:
- Auto-detects remote platform (macOS/Linux)
- Uses rsync for efficient file transfer
- Base64-encoded Brewfile transfer (prevents shell injection)
- Applies remote preferences via SSH
Scan system for untracked configuration files:
dots discover # Interactive discoveryFeatures:
- Recognizes 210+ known config patterns
- Smart profile suggestions based on config category
- Scans configurable paths
- Respects ignore patterns
Sync Brewfile from installed Homebrew packages (macOS only):
dots brewfile # Generate/update Brewfile
dots brewfile -n # Dry runRuns brew bundle dump --all and saves to your dotfiles directory.
Manage configs, profiles, and settings:
dots edit # Interactive editorOptions:
- Add/remove/edit config entries
- Manage profiles
- Configure discovery settings
Usage: dots [command] [options]
Commands:
(none) Interactive menu
init Initialize dots configuration
backup Backup flow (discover, backup, prefs)
deploy Deploy flow (packages, configs, prefs)
edit Edit manifest (configs, profiles)
remote Deploy to remote machine via SSH
brewfile Sync Brewfile from installed packages
discover Scan for new configuration files
Options:
-h, --help Show help message
-v, --version Show version
-p, --profile Use specific profile (minimal, dev, full)
-f, --force Skip confirmation prompts
-n, --dry-run Preview changes without applying
-a, --all Backup all tracked configs (non-interactive)
-y, --yes Auto-confirm prompts
Configuration is stored at ~/.config/dots/config.json.
{
"version": 1,
"syncBrewfile": true,
"configs": [...],
"profiles": [...],
"discovery": {...},
"defaults": {...}
}Each config entry defines a file or directory to sync:
{
"id": "zshrc",
"name": "Zsh Config",
"source": {
"darwin": "~/.zshrc",
"linux": "~/.zshrc"
},
"dest": ".zshrc",
"type": "file",
"profiles": ["minimal", "dev", "full"],
"exclude": ["*.cache"],
"secret": false,
"description": "Zsh shell configuration"
}| Field | Required | Description |
|---|---|---|
id |
Yes | Unique identifier |
name |
Yes | Display name |
source |
Yes | Platform-specific source paths |
dest |
Yes | Destination path in dotfiles dir |
type |
Yes | file or directory |
profiles |
No | Which profiles include this config |
exclude |
No | Glob patterns to exclude (directories only) |
secret |
No | Mark as sensitive |
description |
No | Human-readable description |
Profiles group configs for different use cases:
{
"profiles": [
{
"name": "minimal",
"description": "Essential configs only",
"includes": ["zshrc", "zshenv", "gitconfig"]
},
{
"name": "dev",
"description": "Development setup",
"extends": ["minimal"],
"includes": ["neovim", "lazygit", "bat"]
},
{
"name": "full",
"description": "All configs",
"extends": ["dev"],
"includes": ["*"]
}
]
}includes- Array of config IDs, or["*"]for allextends- Inherit configs from other profiles (with cycle detection)
Configure where to scan for configs:
{
"discovery": {
"scanPaths": {
"darwin": ["~/.config", "~/Library/Application Support", "~"],
"linux": ["~/.config", "~/.local/share", "~"]
},
"ignore": ["*.log", "*.cache", "node_modules", ".git"]
}
}Platform preferences are stored in the manifest:
{
"defaults": {
"darwin": {
"dock": {
"com.apple.dock": {
"autohide": true,
"tilesize": 48
}
}
},
"linux": {
"gnome": {
"org.gnome.desktop.interface": {
"color-scheme": "prefer-dark"
}
}
}
}
}~/.config/dots/
├── config.json # Main configuration manifest
└── dotfiles/ # Synced configuration files
├── .zshrc
├── .gitconfig
├── .config/
│ ├── nvim/
│ ├── starship.toml
│ └── ...
└── Brewfile
Discovery recognizes 210+ configurations including:
- Shells: zsh, bash, fish, nushell
- Editors: neovim, vim, vscode, cursor, emacs
- Terminals: alacritty, kitty, wezterm, ghostty, iterm2
- Multiplexers: tmux, zellij
- Git: gitconfig, gh, lazygit
- CLI tools: starship, bat, ripgrep, fzf, zoxide, atuin
- File managers: yazi, ranger, lf
- Window managers: i3, sway, hyprland, aerospace, yabai
- DevOps: aws, gcloud, kubectl, terraform, docker
- AI tools: claude, aider, continue, copilot
- Dock: autohide, tile size, magnification, position
- Finder: sidebar, status bar, path bar, extensions
- Keyboard: repeat rate, key delay
- Trackpad: tap to click, three-finger drag
- Screenshots: location, format, shadow
- Menu bar: clock format
- GNOME interface: color scheme, themes, fonts
- Window manager: button layout, focus mode
- Keyboard settings
- Path traversal protection: Validates paths stay within allowed directories
- Shell injection prevention: Uses base64 encoding for remote file transfer
- Cycle detection: Prevents infinite loops in profile inheritance
- Manifest validation: Validates schema before saving
MIT