NoiXdev
← All projects
live

dotfix

Keeps several Macs on the same footing — Homebrew packages, shell configuration and config files, grouped into sets that each machine activates on its own. Changes nothing without asking, and never silently overwrites a file you edited by hand.

What it is

A second Mac starts out as a week of small annoyances: the package you forgot to install, the alias that only exists on the other machine, the config file you edited once and never copied over.

dotfix takes the declarative route: you describe what a machine should have — dotfix reports what differs and changes only what you approve. Nothing is applied behind your back, and a file you edited by hand is never silently overwritten. It ships as a command-line tool and a menubar app; both drive the same steps.

Highlights

  • Sets instead of one big configuration — a set bundles a package list, shell fragments and managed files. Each machine activates only the sets it needs.
  • Generated shell configuration — .zshrc is built from the fragments of the active sets. Turning a set off removes its lines again instead of leaving leftovers behind. Anything machine-specific lives in a separate file that the generated one sources at the end.
  • Files as templates — paths and values are filled in as they are written, so nothing is tied to a single machine.
  • It knows who changed what — dotfix compares three things: what the repository wants, what is on the machine, and what dotfix itself last wrote. That third one is what tells “another Mac added this” apart from “I removed it here on purpose”.
  • Nothing without confirmation — every difference is reported and explained, anything overwritten is backed up first, and a diverged repository is reported rather than merged.
  • Credentials stay out — a set refers only to a logical name; where that name lives is the machine’s decision (macOS Keychain, 1Password, or an encrypted file). Files that resolve a secret are written restrictively, values are redacted from all output, and dotfix refuses to adopt files that look like credentials, proposing a template instead.
  • Hourly background check — a background agent writes a single status line that your shell prints at startup. When nothing differs it prints nothing at all; reading it is a file access and costs nothing per terminal tab.
  • Your data, your repository — the configuration lives in a private git repository that belongs to you. dotfix itself stores nothing about you.

Tech stack

  • Rust (edition 2024) as a Cargo workspace: core, command line, and the app backend
  • Tauri 2 with React 19, TypeScript and Tailwind CSS 4 for the menubar app
  • The drift engine in the core talks to Homebrew, the filesystem and git only through traits, which makes all of it testable against in-memory fakes
  • macOS builds are signed and notarized; a release aborts when a signature is missing rather than shipping a warning on first launch

Install

brew tap NoiXdev/tap
brew install dotfix

The menubar app is optional: open the DMG from the latest release and drag dotfix into Applications.

Then set the machine up — from whichever side you prefer, both run the same steps:

dotfix init --set-up-new   # first machine: build a repository from this Mac
dotfix init                # every machine after that: clone and apply

Day to day it is dotfix status (only reports, never writes), dotfix apply, dotfix adopt for whatever grew locally, and dotfix doctor to verify the setup.

For developers

git clone https://github.com/NoiXdev/dotfix.git
cd dotfix
cargo test --workspace

Status

dotfix is LIVE (v1.0.x) and under active development. Issues and PRs are welcome — github.com/NoiXdev/dotfix.