# Install (/docs/haus/install)



```sh
curl -fsSL https://hausfold.co/haus.sh | bash
```

That installs Nix if you don't have it, asks a few questions, and writes your
config. Piped or not, it reaches your terminal and interviews you. It does
**not** change your Mac on its own: it writes files, prints the one command that
activates them, and offers to run that for you, so you can stop in between and
read what it wrote.

What it installs is the **foundation**: the `haus` CLI, the shell, the app
roster and the rebuild plumbing, with no desktop selected. &#x2A;*No bar, no tiling,
no palette, no wallpaper, no hotkey claimed.** What does change is the handful
of macOS defaults haus sets (Dock autohide, key repeat, file extensions in
Finder), and the installer asks which of those to keep as yours. From there you
turn rooms on one line at a time, or select a desktop, a starter template that
turns a whole set on at once. [Choose a desktop](/docs/haus/desktops/choosing)
is both halves.

Want the desktop from the start? Name it in the URL, or give `bash` a flag:

```sh
curl -fsSL https://hausfold.co/hacker.sh | bash                    # the hacker desktop
curl -fsSL https://hausfold.co/haus.sh   | bash -s -- --desktop=hacker   # the same, as a flag
```

A desktop is a set of values for the same options, so anything one chose your
own file overrides in a line. Changing your mind is `haus desktop`, not a
reinstall.

`--desktop` also takes a flakeref, so a desktop someone else published installs
on the same line:

```sh
curl -fsSL https://hausfold.co/haus.sh | bash -s -- --desktop=github:ada/writer-desktop
```

Anything with a `:` or a `/` in it is read as a source rather than a name, so a
`git+https://git.example.org/ada/desktop` clone or a lone
`file+https://example.org/writer.nix` works the same way, and every bare name
still means what it did. Nothing is written until the source passes
`haus show`, which fetches it, checks it is data and not code, and prints the
whole report of what it sets. A failure ends the install there, with nothing
written. What gets written then is the edit
[`haus add`](/docs/haus/reference/haus#pinning-a-desktop-you-found) makes: the
source pinned as an input named off the repo (`writer`), and the line selecting
it. One third-party desktop at a time, and `haus remove writer` unpins it.

None of this needs a listing on this site. A desktop gets a short
`hausfold.co/<name>.sh` URL only when hausfold publishes it; anything else
installs by flag. Publishing one of your own is
[Share a desktop](/docs/haus/desktops/sharing).

```sh
# read it first, or pin an exact release and diff it against GitHub
curl -fsSL https://hausfold.co/haus.sh | less
curl -fsSL 'https://hausfold.co/haus.sh?ref=v2026.07.19' | less
```

The URL proxies
[`bootstrap.sh`](https://github.com/hausfold/haus/blob/main/bootstrap.sh) from
the public repo. A desktop's URL serves that file with two lines added at the
top naming the desktop, so `haus.sh` is the one to diff. You get the latest
release by default, tags are dated, and a **release tag is the only thing
`?ref=` accepts**: anything else is refused rather than fetched, so a link
carrying someone else's commit can't serve you a script off this domain.

## Before you start [#before-you-start]

* A **Mac on Apple Silicon**, running a recent macOS. Intel isn't supported.
* **Xcode Command Line Tools.** The installer prompts for them if they're
  missing, then asks you to re-run.
* **10–15 minutes** and a few GB of download for the first build.

## What it does [#what-it-does]

**Takes a rewind point.** A Time Machine local snapshot, before anything
mutates. If Time Machine is off it warns and carries on.

**Asks its questions.** Your git name and email, an accent colour, and an
editor. haus installs the one you name, Zed, VS Code, Cursor, helix, neovim, vim
or nano, or "other" for a command of your own that haus points at and does not
install. It does not ask which desktop, and it does not ask about the wallpaper:
the foundation leaves the picture alone, and a desktop that wants one says so
itself. The three
apps arrive as casks, adopting a copy already on your Mac rather than laying
down a second one. Then whether to keep your current Dock, keyboard and Finder
settings, and whether to adopt the Homebrew casks you already have.

**Shows a read-only report.** Which dotfiles get backed up, which macOS settings
change, which casks it found.

<Callout type="warn" title="Dotfiles that would stop the first switch">
  The report names any file that would **stop** the switch rather than be backed
  up: a dotfile that is a *symlink* (a dotfiles repo, `stow`, `chezmoi`), or one
  whose `<file>.backup` name is taken. Home Manager moves regular files aside and
  refuses links on purpose, because silently deleting a link into your dotfiles
  repo is the worse failure.
  Clear each one it lists, or tell haus to skip that file
  (`home.file.".profile".enable = false;`), before the build.
</Callout>

**Writes `~/.config/nix/` and commits it to git.** A small flake importing haus,
plus a host file of your answers. &#x2A;*No app you installed is ever removed.**

**Offers to activate.** Nothing is live yet. The last thing it asks, wherever
there's a terminal to ask on, is whether to run the two commands below, then
`haus doctor`. Unattended it stops here and prints them.

## Build and switch [#build-and-switch]

```sh
cd ~/.config/nix
nix build .#darwinConfigurations.$(scutil --get LocalHostName).system \
  && sudo ./result/sw/bin/darwin-rebuild switch --flake .
```

The build runs first, so a failed build never touches your system. &#x2A;*The first
run is slow; it's downloading the world.** When it lands, everything arrives at
once: apps install, the bar and tiling start, your terminal is themed, `haus`
joins your `PATH`. After that it's `haus rebuild`.

## If you regret it [#if-you-regret-it]

| To undo             | Use                                                               |
| ------------------- | ----------------------------------------------------------------- |
| The macOS settings  | the Time Machine snapshot the installer took                      |
| Everything haus did | `haus rollback` (atomic, previous generation)                     |
| Apps                | yours. haus never uninstalls one you added                        |
| All of it           | [Leaving](/docs/haus/leaving), every exit in turn, smallest first |

## Unattended installs [#unattended-installs]

Every question has an environment variable, so the whole thing can run without a
prompt:

```sh
HAUS_NONINTERACTIVE=1 \
HAUS_GIT_NAME="Ada Lovelace" \
HAUS_GIT_EMAIL="ada@example.com" \
HAUS_ACCENT="mauve" \
bash -c "$(curl -fsSL https://hausfold.co/haus.sh)"
```

| Variable                                         | Effect                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `HAUS_NONINTERACTIVE=1`                          | Take the defaults, Determinate's own confirmation included, so a run with no terminal at all (ssh, CI, a provisioning wrapper) gets through                                                                                                                                                                                                                                                                |
| `HAUS_DRY_RUN=1`                                 | Print the config it would write, write nothing. Still asks the questions if you have a terminal; pair it with `--defaults` for a silent run                                                                                                                                                                                                                                                                |
| `HAUS_DESKTOP`                                   | `hacker`, or `--desktop=hacker` on the command line: select that desktop instead of the foundation, which is what `hacker.sh` sets. Unset, no desktop is selected. Takes a flakeref to someone else's desktop too (`github:ada/writer-desktop`), on the terms above: checked with `haus show` first, and a failure writes nothing. `blank`, `everyday` and `minimal` are retired spellings that still read |
| `HAUS_ROOMS`                                     | Rooms to turn on from the start, one `enable = true;` host line each: `bar`, `windows`, `launcher`, `shelf`, `focus`, `ai`, `development`, `security`. Ignored when a desktop is selected, since that desktop decides                                                                                                                                                                                      |
| `HAUS_GIT_NAME` / `HAUS_GIT_EMAIL`               | Your git identity, which the host file records                                                                                                                                                                                                                                                                                                                                                             |
| `HAUS_ACCENT` / `HAUS_WALLPAPER` / `HAUS_EDITOR` | The accent, one of the generated wallpaper looks (`minimal`, `orbits`, `constellation`, `flow`, `bold`, or `none`; unset, the foundation leaves your picture alone and a desktop sets its own, which for hacker is `minimal`), and the editor (`zed`, `vscode`, `cursor`, `helix`, `neovim`, `vim`, `nano`)                                                                                                |
| `HAUS_GUI_EDITOR`                                | Point `$EDITOR` at a command haus does not install (e.g. `"subl -w"`); the editor above still installs as fallback                                                                                                                                                                                                                                                                                         |
| `HAUS_KEEP`                                      | macOS settings to leave alone (`dock,keyboard,finder`)                                                                                                                                                                                                                                                                                                                                                     |
| `HAUS_DIR`                                       | Scaffold somewhere other than `~/.config/nix`                                                                                                                                                                                                                                                                                                                                                              |
| `HAUS_FROM`                                      | Restore an existing config instead of scaffolding                                                                                                                                                                                                                                                                                                                                                          |
| `HAUS_PRESET=full`                               | The pre-desktops spelling for `hacker`, still honoured                                                                                                                                                                                                                                                                                                                                                     |

Reach for these if you hand the install to a coding agent: the questions are a
terminal UI, and a tool driving one blind is how someone else's git identity
ends up in your config. An agent can do everything up to the build. The two
`sudo` steps are yours.
