# Leaving (/docs/haus/leaving)



haus has defaults, not demands. Rolling back a generation, switching off one room,
removing the system layer and removing Nix are four operations of very different
sizes. &#x2A;*Start with the smallest one that solves your problem.**

<Callout type="warn" title="Keep your config before you remove anything">
  `~/.config/nix` is *your* machine described in text, not generated state. Archive
  it first; a git remote is better, if it holds no secrets.

  ```sh
  cp -R ~/.config/nix ~/.config/nix.archive
  ```
</Callout>

## Roll back a generation [#roll-back-a-generation]

Every successful switch makes a generation, and stepping back to one takes
seconds:

```sh
haus generations         # what you can go back to
haus rollback            # the previous one
haus rollback <number>   # a specific one
```

That restores everything Nix wrote: packages, agents, shell config, paths. It does
**not** touch macOS's own preferences, which a rebuild sets imperatively: the
Dock, Finder, the keyboard, the menu bar, file associations. Those have
their own pair of commands, and System Settings is the way back if you never
captured a snapshot:

```sh
haus capture              # snapshot the live settings before a risky change
haus revert-settings      # write the snapshot's keys back over the live ones
haus revert-settings list # every snapshot you've taken
```

**The wallpaper is the sharpest case.** The foundation leaves it alone, but
hacker sets `haus.wallpaper.style` to `minimal`, so on that desktop the picture
is stamped at every activation and macOS keeps no record of what was there
before. Rolling back doesn't bring yours back: re-pick it in
System Settings **and** set `haus.wallpaper.style = "none"`, or the next rebuild
stamps over it again.

## Switch off a room [#switch-off-a-room]

Every room comes out independently, and the rest of the machine keeps working:

```nix
{
  haus.windows.enable = false;   # AeroSpace tiling, the Caps-Lock leader, window bindings
  haus.bar.enable = false;    # SketchyBar: the top bar, and the bottom one if you run it
  haus.launcher.enable = false;  # the launcher daemon, ⌘Space, its Accessibility features
  haus.shelf.enable = false;   # the notch file shelf, see the residue note below
  haus.focus.enable = false;    # the quiet switch: its bar pill, palette command and CLI
  haus.security.touchId.enable = false;  # Touch ID for sudo, back to the password prompt
}
```

```sh
haus edit
haus rebuild
```

The native menu bar comes back on its own: haus rewrites that key at every
activation, so switching bar off is enough. Caps Lock comes back on the next **restart**: the remap is a `hidutil`
property that lasts until you reboot, so the session you rebuilt in keeps it.
**Spotlight's ⌘Space** never comes back on its own, because the launcher disables
that shortcut with a one-way write; re-enable it in System Settings ▸ Keyboard ▸
Keyboard Shortcuts. The Focus room leaves the reverse trace: a Do Not Disturb
chord bound onto a shortcut macOS ships disabled, which stays bound until you
clear it.

[Customize a desktop](/docs/haus/desktops/customizing#turning-rooms-off) has the
full table, plus the middle ground where the tiler keeps working but gives your
keys back.

## Take the whole thing off [#take-the-whole-thing-off]

One verb, and it does the four steps below in the only order that works:

```sh
haus uninstall        # prints the plan, asks once
haus uninstall --yes  # skip the question
```

It prints what it is about to remove and what it is going to leave, then puts
your macOS settings back from the snapshot the installer took, removes
nix-darwin, removes every launchd agent haus wrote, removes Nix, and finally
cleans up the dotfile links that have just gone dead. It leaves
`~/.config/nix`, Homebrew and its casks, and your TCC grants, and it names each
one with the command that removes it.

<Callout type="info" title="Why the order matters">
  Each step depends on the one before it. `haus revert-settings` has to run while
  haus is still installed, because it is about to be deleted with everything
  else. The Determinate uninstaller refuses to run at all while nix-darwin is
  installed. nix-darwin removes its two system daemons and leaves the agents in
  `~/Library/LaunchAgents` exactly where they are, so those have to go
  separately, or they come back at every login and respawn every ten seconds
  against a store that is gone. And a Home Manager symlink only reads as dead
  once Nix is removed, so the cleanup has to be last.
</Callout>

The rest of this page is the same route by hand, one step at a time, for a
machine where `haus` is already gone or where you want to stop part way.

## Take down the system layer [#take-down-the-system-layer]

This removes nix-darwin's system integration and leaves Nix installed for
everything else that uses it. Run nix-darwin's own uninstaller, falling back to the
locally installed `sudo darwin-uninstaller` if that can't run:

```sh
sudo nix --extra-experimental-features "nix-command flakes" \
  run nix-darwin#darwin-uninstaller
```

**Read the plan before confirming.** It removes the managed system links, static
files and launchd services, then restores the Nix daemon the installer supplied.

<Callout type="warn" title="It leaves your login agents behind">
  "launchd services" there means the two *system* daemons. Everything haus runs
  in your login session stays in `~/Library/LaunchAgents`, still enabled, and
  once Nix is gone those point at nothing: SketchyBar, AeroSpace and Pounce come
  back at every login and respawn every ten seconds, forever. Take them out
  yourself:

  ```sh
  for p in ~/Library/LaunchAgents/*.plist; do
    grep -q -e /nix/store -e /run/current-system "$p" || continue
    label=$(basename "$p" .plist)
    launchctl bootout "gui/$UID/$label" 2>/dev/null
    rm -f "$p"
  done
  ```

  `haus uninstall` does this for you, which is the reason it exists.
</Callout>

Restart when it finishes. Your config isn't made useless by this: keep it if you might
come back, or move it out of the active path with `mv ~/.config/nix ~/.config/nix.archive`.

### Put your own dotfiles back [#put-your-own-dotfiles-back]

Home Manager preserves a conflicting file with a `.backup` suffix rather than
clobbering it, so what you had before the install is usually still there:

```sh
find "$HOME" -maxdepth 5 -name '*.backup' -print
```

Typically `~/.zshrc.backup`, `~/.zshenv.backup`, `~/.zprofile.backup`,
`~/.profile.backup`, `~/.config/starship.toml.backup`,
`~/.config/git/config.backup`, plus some inside managed directories. `~/.zprofile`
is the one people forget, and where Homebrew's `shellenv` line usually lives.
Inspect each, confirm the Nix-managed target is gone, then move it back by hand.

Deal with `~/.profile` while haus is still installed. haus writes its own, guarded
(an unguarded `. "$file"` naming a file that isn't there prints an error on every
new terminal window), and it sources `~/.profile.local` if you have one. So
anything your old `~/.profile` set (a PATH, a toolchain's `env`) belongs in
`~/.profile.local` until you leave, and comes back with the rest afterwards.

<Callout type="warn">
  Don't restore blindly. A backup is the version that existed at the *first*
  conflict, which may be years older than what you'd want today.
</Callout>

### Apps stay yours [#apps-stay-yours]

haus never removes an app just because it left your config:
`haus.homebrew.cleanup` is `"none"`. Compare what you declared against what
Homebrew owns, and remove only what you don't want:

```sh
brew list --formula
brew list --cask
brew uninstall <formula>
brew uninstall --cask <cask>          # add --zap to take its data too
```

**Pounce installed on its own** is the opposite case. Dropping the launcher room
is `haus.launcher.enable = false` above, but a copy you installed through
Homebrew is yours to take off:
[Remove it](/docs/pounce/install#remove-it) has the commands.

## Remove Determinate Nix [#remove-determinate-nix]

<Callout type="error" title="Only after the system layer is down">
  Removing Nix affects **every** Nix-managed project and tool on the Mac, not just
  haus.
</Callout>

The Determinate installer ships its own uninstaller. Read the plan before
confirming, and restart when it's done:

```sh
sudo /nix/nix-installer uninstall
```

If it fails, follow Determinate's current macOS uninstall guide rather than
deleting pieces of `/nix` by hand.

## What to check afterwards [#what-to-check-afterwards]

No uninstaller can reconstruct every preference that existed before an install.
**`haus revert-settings` is the real answer, and you almost certainly have a
snapshot to give it**: the installer takes one of the Dock, Finder and keyboard
domains before the first switch, so the verb works without your ever having run
`haus capture`. `haus revert-settings list` shows what is there. This list is
for anything outside those three domains, and for an install old enough to
predate the snapshot:

* the Dock's autohide, position, size and animations
* key repeat, press-and-hold, and the trackpad's tap-to-click and three-finger drag
* Finder's extensions, hidden files, path bar and view style
* hot corners
* the native menu bar and its clock, and Caps Lock
* Spotlight's ⌘Space, which never comes back on its own, and the Do Not Disturb
  chord focus bound, which stays bound
* the wallpaper
* where screenshots land and in what format, and the screen-lock delay
* alert volume and the startup chime (that one is firmware, and survives a reinstall)
* your keyboard input sources: haus declares them exhaustively, so layouts you
  never listed were switched off
* the application firewall
* file associations, if `haus.terminal.hijackFileAssociations` was on
* the launcher's Accessibility grant, and Touch ID for `sudo`, including the
  passwordless-`sudo` rule for rebuilds, which is the one with a security
  consequence

The installer also takes an APFS snapshot before it starts, but that one is a
whole-volume restore from Recovery rather than a settings undo, and macOS purges
local snapshots within about a day. Treat it as luck rather than a plan; the
settings snapshot above is the one to reach for. Then confirm what's actually
gone:

```sh
command -v haus || echo "haus is no longer on PATH"
command -v darwin-rebuild || echo "darwin-rebuild is no longer on PATH"
launchctl list | grep -Ei 'hausfold|pounce|aerospace|sketchybar|bar|focus|sleepwatcher'
```

Keep that pattern wide: haus runs more agents than the obvious three, under three
different label prefixes, and a narrower grep reports a clean machine while the
bottom bar and the focus watcher are still loaded. A surviving AeroSpace or
SketchyBar process isn't automatically residue: both are Homebrew installs haus
only *launches*, so `brew uninstall` is what removes them. And nothing has a
removal path for the shelf app an activation step copied into place, or for state
written as the machine ran:

```sh
ls ~/.local/state/haus ~/.local/state/pounce ~/.config/perch /Applications/Perch.app
```

## If something stays behind [#if-something-stays-behind]

A departure that doesn't complete is a bug worth reporting. [Open an
issue](https://github.com/hausfold/haus/issues) with your Mac model and macOS
version, whether Nix existed before haus, the path you followed, the exact command
and its output, and what remained. Strip tokens, keys and personal files out of
anything you paste.
