hausfold

haus

Install

One line scaffolds your config. A second command activates it. Nothing is activated without your say-so.

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

That installs Nix if you don't have it, asks you a few questions (including which desktop you want), and writes your config. It does not change your Mac on its own: it writes files, prints the one command that activates them, and asks before running it for you.

So the whole install is two moves, and you can stop between them and read what the first one wrote. (The pipe doesn't cost you the questions: the installer reaches your terminal directly, so | bash interviews you like any other form. In CI, a container, or a run whose output you've captured to a file, no one is watching, so it takes the defaults and never offers to switch.)

If you already know which desktop you want

Every desktop has its own URL, and typing it answers the question before it's asked:

curl -fsSL https://hausfold.co/hacker.sh    | bash   # the full desktop
curl -fsSL https://hausfold.co/everyday.sh  | bash   # for someone who doesn't write code
curl -fsSL https://hausfold.co/minimal.sh   | bash   # just the themed shell

They're the same script: the URL sets the desktop and the installer skips that one question. haus.sh is the one that asks. A Mac runs exactly one desktop, and whichever you pick, changing your mind later is a line in your own config, not a reinstall.

Piping to bash passes no arguments, which is why the desktop rides in the URL rather than on a flag. If you'd rather use the flag, give bash a -s --:

curl -fsSL https://hausfold.co/haus.sh | bash -s -- --desktop=minimal

A desktop is not a lock-in

Every desktop is a set of values for the same options. Anything one of them chose, your own file overrides in a line, so picking is a starting point, not a commitment.

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.

You don't need Nix first

The bootstrap installs Determinate Nix for you. If you already run stock Nix it stops and explains rather than touching your install.

Read it first, if you like

curl … | bash runs whatever the URL serves, so it's fair to want to look. The URL only proxies bootstrap.sh from the public repo; it's boring on purpose.

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

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

A desktop's URL serves that same file with two lines added at the top, saying which desktop you asked for. haus.sh adds nothing at all, so it's the one to diff against GitHub.

By default you get the latest release tag. Releases are date-tagged, so ?ref=v2026.07.18 pins a specific day, and a release tag is the only thing ?ref= accepts. Anything else is refused rather than fetched, which is what stops a link with someone else's commit in it from serving you a script off this domain.

What it does

Takes a snapshot

Confirms you're on macOS and takes a Time Machine local snapshot as a coarse rewind point. Non-fatal if Time Machine is off.

Asks you a few things

Your git name and email, a desktop (hacker / everyday / minimal / custom), an accent colour, a wallpaper, and an editor: helix, neovim, vim or nano, and haus installs the one you name. It also asks whether to keep your current Dock, keyboard and Finder settings, and whether to adopt the Homebrew casks you already have.

Shows you what would change

A read-only report before anything is written: which dotfiles get backed up, which macOS settings change, and which casks it found. No app you installed is ever removed.

Writes your config

Creates ~/.config/nix/ (a small flake that imports haus, plus a host file holding your answers) and commits it to git.

Nothing is active yet. Wherever there's a terminal to ask on, piped or not, the last thing it asks is whether to change that: say yes and it runs the two commands below for you, then haus doctor. Unattended, it stops here and prints them.

Build and switch

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

The build runs first, and a failed build never touches your system. When it succeeds, everything lands at once: apps install, the bar and tiling start, your terminal is themed, and haus joins your PATH.

The first run is slow; it's downloading the world. After that, haus rebuild is the only command you need.

If you regret it

To undoUse
The macOS settingsthe snapshot from step 1
Everything haus didhaus rollback (atomic, previous generation)
Appsyours. haus never uninstalls one you added
All of itLeaving, every exit in turn, smallest first

Unattended installs

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

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)"
VariableEffect
HAUS_NONINTERACTIVE=1Skip the questions, take the defaults
HAUS_DRY_RUN=1Print 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_DESKTOPWhich desktop to select (hacker, everyday, minimal, blank), or --desktop=<name> on the command line. Setting it skips that question even in an interactive run, which is what a desktop's own URL does for you
HAUS_ROOMSWhich rooms to turn on, one by one, instead of taking a desktop's selection
HAUS_ACCENT / HAUS_WALLPAPER / HAUS_EDITORThe look and the editor
HAUS_KEEPmacOS settings to leave alone (dock,keyboard,finder)
HAUS_DIRScaffold somewhere other than ~/.config/nix
HAUS_FROMRestore an existing config instead of scaffolding

If you already scripted this with the old names

Every variable above was spelled NEBELHAUS_* until 2026-08-14, and the old spelling is still read: the installer promotes it before anything else runs, with the new name winning if both are set. Same for the desktop names it accepts: hacker was nebelhaus, and the pre-desktops HAUS_PRESET=full still selects it. Nothing you already automated needs changing.

These are also what you want if you hand the install to a coding agent: the questions are a terminal UI, and a tool driving it 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.

Next

On this page