Alternatives β
Most tools here do part of what a developer machine needs. This collection's niche is the whole of it, packages, system config, repositories, and dotfiles, for one laptop or a fleet, from one repo. It straddles two categories, so it's compared against each on its own terms: dotfiles managers and provisioners.
TLDR
Only syncing files in $HOME? chezmoi is simpler, use it. Want packages, system state, and repositories managed alongside your dotfiles? that's this collection. The gap is scope, not capability: chezmoi's file engine and Ansible's template/copy under --diff do the same thing, they part ways on everything around the file.
Prefer a focused, one-on-one comparison? See Dotfiles Pro vs chezmoi, yadm, GNU Stow, dotbot, bare git, Nix home-manager, Salt, Puppet, Chef, MDM, devcontainers, or golden images.
- β supported
- π‘ partial, or via scripts/add-ons
- β not supported / out of scope
When to choose what β
- chezmoi: files in
$HOMEare all you'll manage. Add packages or system state and it falls back to run scripts, now you maintain two tools. - Nix: reproducibility and rollback matter more to you than learning curve.
- Landscape / MDM: the company must enforce state; personal setup is out of scope.
- Devcontainers: per-project toolchains are the pain point; use them with this collection.
- Dotfiles Pro: an Ubuntu, macOS, or WSL machine (or twenty) that needs packages, system state, repositories, and dotfiles managed together, in tech the team already reads, adoptable role by role.
Dotfiles managers β
Everything a dotfiles manager does, this does too. The difference starts at the Machine state rows, where file-focused tools fall back to setup.sh-style hooks and community plugins.
| Feature | Dotfiles Pro | chezmoi | yadm | Stow / dotbot / bare git |
|---|---|---|---|---|
| Website | dotfiles.pro | chezmoi.io | yadm.io | Stow Β· dotbot |
| Stars | β | |||
| Approach | ||||
| Mechanism | local Ansible run | binary + file source | git in $HOME | symlink farm |
| Primary scope | whole machine | home-dir files | home-dir files | home-dir files |
| Learning curve | low (YAML) | low | low | minimal |
| Configuration files | ||||
| Dotfile management | β | β | β | β |
| Per-machine templating | β | β | β | β |
| Key-level changes to software-written files | β | π‘ | β | β |
| Secrets integration | β | β | π‘ | β |
| Machine state | ||||
| Package installation | β | π‘ | π‘ | π‘ |
| System configuration (services, sysctl, wsl.conf) | β | π‘ | π‘ | π‘ |
| Repository cloning | β | π‘ | β | β |
| Operations | ||||
| Idempotent drift repair | β | β | β | π‘ |
| Targeted partial runs (tags) | β | β | π‘ | β |
| Minimal bootstrap (single binary/script) | β | β | β | β |
| Team & fleet | ||||
| Shared baseline + personal overrides | β | π‘ | β | β |
| Fleet-wide rollout without reimaging | β | β | β | β |
| Platforms | ||||
| Ubuntu | β | β | β | β |
| Other Linux distributions | β | β | β | β |
| WSL with Windows-side integration | β | β | β | β |
| Windows (native) | β | β | π‘ | π‘ |
| macOS | π‘ | β | β | β |
Only Dotfiles Pro also manages the machine itself, not just the files in $HOME.
Reading the table, key-level edits, secrets, machine state, platforms
- chezmoi keeps its own comparison table of dotfiles-only tools, with no rows for packages or system state, which is the scope gap. Its design FAQ draws the same line from the other side: past "a handful of files⦠Puppet, Chef, Ansible, and Salt are much better suited", and chezmoi "will always be personal home directory management", their words for the scope-not-capability framing.
- Key-level edits: config files have three authors, you, the software's defaults, and the software at runtime (credential helpers, kubeconfig token refreshes). Commit the whole file and you pin stale defaults and fight runtime writes; key-level management owns only the keys you declare (chezmoi reaches this partially via
modify_scripts). The trade-off: whole-file repos give yougit diffover every change at the price of churn; key-level moves the diff to apply time (diff: true) and leaves churn to the software. - Verbatim files too: key-level is the default, not a mandate. Files happiest committed whole (a hand-tuned
starship.toml, a long.bashrc,AGENTS.md) go through thedotfilesrole, which links, copies, or templates them into$HOME. The two approaches coexist on one path: the config roles write through a symlinked target (follow: true, andgit confignatively), so you can link a file with thedotfilesrole and still let a role drive its keys, picking settings-driven or verbatim per file. - Capturing existing config: chezmoi's
re-addre-imports the whole file (current defaults, churn, and any secrets); the planneddotpro capture(roadmap) extracts the reviewed, structured delta as vars, the key-level answer to "but chezmoi canre-addand you can't." - One source vs many (their edge): chezmoi mandates a single source directory, sidestepping "which source does
addwrite to?"; Dotfiles Pro accepts multiple sources (collection / personal / company) for modularity and pays that ambiguity, most concretely in wherecapturelands. - Secrets: yadm has built-in encryption but no password-manager integration (π‘).
- Machine state: the Stow/dotbot/bare-git π‘s belong to dotbot alone, its
shelldirective and apt/brew plugins reach packages; Stow and a bare repo do not. - Platforms: Ubuntu, macOS (the
macosrole, Homebrew), and WSL; other distros ride the sameansible_facts.os_familyguards; running on Windows without WSL is out of scope by design, but a WSL machine's Windows half is managed: thewslrole bridges WSL tools into Windows and thewindowsrole converges winget apps, registry values, and virtual desktops over interop.
Provisioners β
Against machine-level tools the comparison flips: everyone installs packages. What sets Dotfiles Pro apart is the personal layer, gradual adoption, and pull-based developer ownership.
| Feature | Dotfiles Pro | Nix HM / NixOS | Salt / Puppet | Landscape / MDM | Devcontainers | Golden image |
|---|---|---|---|---|---|---|
| Website | dotfiles.pro | nixos.org | saltproject.io Β· puppet.com | ubuntu.com/landscape | containers.dev | autoinstall docs |
| Stars | β | β | β | |||
| Approach | ||||||
| Mechanism | local Ansible run | declarative build | masterless CM | agent + server | container image | one-shot installer |
| Primary scope | whole machine | OS + home | whole machine | fleet policy | per project | day-0 OS |
| Learning curve | low (YAML) | very high | medium | n/a (product) | low | low |
| Configuration files | ||||||
| Dotfile management | β | β | β | β | π‘ | π‘ |
| Per-machine templating | β | β | β | β | β | β |
| Key-level changes to software-written files | β | β | β | π‘ | β | β |
| Secrets integration | β | π‘ | β | π‘ | π‘ | β |
| Machine state | ||||||
| Package installation | β | β | β | β | π‘ | β |
| System configuration (services, sysctl, wsl.conf) | β | β | β | β | β | β |
| Repository cloning | β | π‘ | β | β | π‘ | π‘ |
| Operations | ||||||
| Idempotent drift repair | β | β | β | β | β | β |
| Reproducible builds / atomic rollback | β | β | β | β | π‘ | π‘ |
| Targeted partial runs (tags) | β | β | β | β | β | β |
| No agent or server required | β | β | π‘ | β | β | β |
| Team & fleet | ||||||
| Shared baseline + personal overrides | β | β | β | π‘ | π‘ | β |
| Fleet-wide rollout without reimaging | β | β | β | β | π‘ | β |
| Central enforcement & compliance | β | β | π‘ | β | β | β |
| Gradual adoption on existing machines | β | β | π‘ | π‘ | β | β |
| Platforms | ||||||
| Ubuntu | β | β | β | β | β | β |
| Other Linux distributions | β | β | β | π‘ | β | π‘ |
| WSL with Windows-side integration | β | β | β | β | π‘ | β |
| Windows (native) | β | β | β | β | β | π‘ |
| macOS | π‘ | β | β | π‘ | β | β |
Only Dotfiles Pro and Nix home-manager genuinely belong to both categories.
Reading the table, devcontainers, golden images, MDM, home-manager
- Devcontainers manage everything inside the container but leave the machine unmanaged, they compose with Dotfiles Pro, not compete.
- A golden image does real machine setup, but once: every π‘ means "at install time only."
- Landscape/MDM is the only push model, the company owns machine state, not the developer.
- home-manager is the strictest file owner (whole files generated, often read-only): maximally declarative, but it fights software that writes its own config.
- Salt/Puppet can template files into
$HOMEbut offer no personal dotfiles workflow (π‘).
One machine is one job β
"Use the right tool for each job" is good advice, but a developer machine is one job, not four. Packages, config, repositories, and shell state interlock: an alias is useless without its tool, a kubeconfig stanza needs its CLI. Split that across a dotfiles manager, an installer, and glue scripts, and the integration lands on an untested setup.sh.
This collection takes one engine built from the specialists, apt still installs, git still clones, starship owns the prompt; roles declare them, not reimplement them. Compose at the real boundaries instead: project (devcontainers), enforcement (MDM), secrets (your password manager).
The wall isn't a missing feature, it's the first time a config has to do something instead of just be a file: take a value that differs per machine, live in a format with nowhere to hang a symlink directive (JSON), trigger the install of the tool it configures, or pull a secret. A symlink farm or a comment-parsing script has no answer to any of those, that's where managing files turns into provisioning a machine.
The landscape in four families
- Dotfiles-only managers (chezmoi, yadm, Stow, dotbot, bare git), simpler than Ansible, but they manage files, not machines. The gap fills with
setup.sh; chezmoi's own run scripts exist "to handle everything else", and projects like install.doctor bolt a full Ansible provisioner onto chezmoi, the scope gap, externalized. The imperative remainder roles fold in. - Other configuration management (masterless Salt, Puppet, Chef), the same idea with a different DSL and a smaller laptop community.
ansible-pullis a cron variant; central-push products (AWX, MDM) flip ownership to the company. - The OS as the artifact (NixOS, home-manager, Fedora Silverblue), stronger guarantees (reproducible builds, atomic rollback) at the cost of the steepest learning curve and an all-or-nothing migration.
- Moving up the stack (devcontainers, Codespaces, Gitpod), standardize the project, not the machine; they compose, since the laptop still needs git, Docker, SSH, identity, and shell setup.
Migrating in β
Coming in is incremental, by design. Adopt one role at a time; whatever you haven't migrated keeps working, because nothing here touches files it doesn't manage. Run your old tool and the playbook side by side until the playbook owns everything, then retire the old one.
From chezmoi. Your source directory is the inventory of what to move. Structured config (git identity, aliases, tool settings) becomes role vars (the key-level model), so roles own those keys instead of whole files; per-machine .tmpl files become host_vars / group_vars plus the roles' Jinja; files chezmoi only copies verbatim map to a role's files/ or a ~/.profile.d/ drop-in.
There's no automatic importer yet, dotpro capture is on the roadmap, so it's a one-time, reviewable translation, done role by role.
From Stow or bare git. Replace the symlink farm with roles that write real files: a Stow package becomes a role (or a ~/.profile.d/ snippet), and the symlinks become templated or copied files, so nothing dangles when the source moves. Packages you only ever stow'd unchanged are easiest, drop them into a role's files/ and you're done.
Either way you gain what the old tool couldn't reach: the packages, system config, and repositories around those files, managed in the same run.
Getting out β
Leaving costs nothing, by design. No agent, no daemon, no symlinks into a source repo, roles write ordinary files, install ordinary packages, clone ordinary repos. Stop running the playbook and the machine keeps working exactly as last applied; it just stops applying. Your configuration survives as portable YAML. (Stow's symlinks dangle, home-manager's files live in /nix/store, MDM needs unenrollment, none of that here.)
One caveat: vars you remove leave their artifacts on disk until you clean them up by hand, automating that is a roadmap item.