# Choose a desktop (/docs/haus/desktops/choosing)



**haus supplies rooms. A desktop curates them. Your host file makes one yours.**

A **room** is one capability (the bar, the launcher, window management) with its
own options and its own switch. A **desktop** is a starter template: a complete
answer to &#x2A;what should this Mac feel like?*, with which rooms are on and what the
visible choices are. Your **host file** is where your name, your keys and your
own overrides live.

```text
haus foundation          the rooms, their options, safe defaults
      ↓
one desktop, or none     hacker, one you found, or nothing at all
      ↓
your host file           identity, secrets, hardware, and any override
      ↓
`haus set`               what the palette and your agent write for you
```

Later layers win, deliberately. Anything a desktop chose, you change with a
plain assignment in your host file: no `lib.mkForce` anywhere.

## None: the foundation [#none-the-foundation]

The installer selects no desktop. Your `flake.nix` says so in one line, and the
line is written out rather than left off, because leaving it off means
something else (below):

```nix
desktop = null;
```

What you get is the foundation, and only that:

* **the `haus` CLI**: `rebuild`, `plan`, `diff`, `set`, `rollback`, `update`;
* **zsh**, enabled with no switch of its own. The shell *experience* (a tinted
  prompt, git, the toolbelt) is [Development](/docs/haus/rooms/development)'s;
* **the app roster**: the one list driving what's installed and from where,
  ready for entries you add;
* **the Nix and rebuild plumbing**: pinned inputs, generations, garbage
  collection;
* **haus's safe macOS defaults**, nearly all of them soft, so your host outranks
  them with a plain assignment. ([Two menu-bar keys are
  not](/docs/haus/desktops/customizing#beating-a-default-haus-set), and say so.)

What you don't get is anything on screen. No optional room is on: no bar, no
tiling, no launcher, no shelf, no coding agents, no developer toolbelt, no Touch
ID for `sudo`. No global hotkey is claimed: Caps Lock stays Caps Lock, ⌘Space
stays Spotlight's. The wallpaper is left alone, the tour doesn't run, and no
theme files are written into apps you already had. The one thing that does
change is the macOS defaults above, softly, and the installer asks which of the
Dock, keyboard and Finder settings to keep as yours.

From there, every room is one line in your host file, or one command:

```sh
haus set bar.enable true       # the bar
haus set launcher.enable true  # the launcher
haus set keys.palette cmd-space
haus rebuild
```

A room enabled is a room that works: each ships a neutral, useful configuration,
so the bar draws and the launcher opens with nothing tuned. Tune it from that
room's page afterwards, or leave it. [Rooms](/docs/haus/rooms) is the list.

<Callout title="Rooms don't switch each other on">
  Turning on the Bar doesn't bring the launcher, and Development doesn't bring
  coding agents. Where two rooms cooperate (agent pills on the bar, agent commands
  in the launcher) the extra appears only when *both* are on, and its absence
  never disables the room that offered it.
</Callout>

Turning on most of the catalogue means you are describing a desktop that already
exists: select it and override the two or three things you disagree with. If what
you have is genuinely yours and you want it on a second Mac, that's a [desktop of
your own](/docs/haus/desktops/creating).

## Exactly one, or none [#exactly-one-or-none]

A Mac runs **one** desktop, or none. They don't stack, and the build says so:
selecting two is refused whether they disagree or not, and so is selecting the
same one twice, with a message of its own. Choosing again changes one line rather
than unpicking a pile, and "build my own" is the foundation plus your host file
rather than a second mode with its own rules.

## The gallery [#the-gallery]

Every desktop this site presents: the ones hausfold serves from their own URL
first, then the ones that install by flakeref. Each card is one row of the table
`/v1/desktops` serves, so a reader and an agent asking for an install command are
told the same thing.

A card lists the rooms a desktop *switches on*.
[Appearance](/docs/haus/rooms/appearance) has no switch of its own, so it is
never in the list even when a desktop picks the accent and the font through it.

{/* desktops:start — rendered from worker-config.js's DESKTOPS by `npm run desktops`.
    Edit the row, not this block: `npm run desktops:check` reverts a hand edit. */}

### The foundation [#the-foundation]

**By hausfold.** The layer and nothing on screen: the haus CLI, the shell, the
app roster and the rebuild plumbing, with every optional room left off.

It switches no room on, which is the whole of what it is. [What you get, in
full](#none-the-foundation).

```sh
curl -fsSL https://hausfold.co/haus.sh | bash   # a fresh Mac
haus desktop none && haus rebuild               # one that has haus already
```

### hacker [#hacker]

**By hausfold.** Keyboard-first, for someone who writes code all day: tiled
windows, a bar, the palette on ⌘Space, coding agents and a themed terminal.

Rooms it switches on: [Development](/docs/haus/rooms/development),
[Windows](/docs/haus/rooms/windows), [Bar](/docs/haus/rooms/bar),
[Launcher](/docs/haus/rooms/launcher), [Shelf](/docs/haus/rooms/shelf),
[Focus](/docs/haus/rooms/focus), [AI](/docs/haus/rooms/ai),
[Security](/docs/haus/rooms/security). [hacker's own
page](/docs/haus/desktops/hacker) has the first moves that make it click.

```sh
curl -fsSL https://hausfold.co/hacker.sh | bash   # a fresh Mac
haus desktop hacker && haus rebuild               # one that has haus already
```

### producer [#producer]

**By hausfold**, at
[`github:hausfold/producer-desktop`](https://github.com/hausfold/producer-desktop).
A studio Mac, built around Ableton, RX and Resolve and leaving all three alone:
the palette opens on ⌘Space, and the tiler stays off so Caps Lock is still Caps
Lock.

Rooms it switches on: [Bar](/docs/haus/rooms/bar),
[Launcher](/docs/haus/rooms/launcher), [Shelf](/docs/haus/rooms/shelf),
[Focus](/docs/haus/rooms/focus), [Security](/docs/haus/rooms/security).

There is no `hausfold.co/producer.sh`: a short installer URL here is one
hausfold publishes, and every other desktop installs by flakeref instead. `haus
show github:hausfold/producer-desktop` prints what it would change before you
pin it.

```sh
# a fresh Mac
curl -fsSL https://hausfold.co/haus.sh | bash -s -- --desktop=github:hausfold/producer-desktop
# one that has haus already
haus add github:hausfold/producer-desktop && haus rebuild
```

{/* desktops:end */}

<Callout title="A desktop claims more than its rooms">
  The rooms are the visible half. A desktop also makes machine-wide claims, and
  those are what a rebuild would take from you: hacker ports the theme into apps
  you already use, generates a wallpaper, and claims Caps Lock as the leader and
  ⌘Space as the palette. producer claims ⌘Space and leaves Caps Lock alone.
  `haus plan` lists what a rebuild would change here, leaf by leaf, and `haus show <flakeref>` does the same for a desktop you have not selected yet.
</Callout>

## Selecting and switching [#selecting-and-switching]

Your `~/.config/nix/flake.nix` names the desktop in one line, and `haus desktop`
reads and rewrites that line so you don't have to:

```nix
darwinConfigurations.lovelace = haus.mkHaus {
  username = "ada";
  hostname = "lovelace";
  host = ./hosts/lovelace;
  desktop = haus.desktops.hacker;   # or null for the foundation
};
```

```sh
haus desktop            # none, the built-in desktops, and any you pinned; → marks the current one
haus desktop hacker     # select hacker
haus desktop none       # back to the foundation
haus rebuild            # nothing changes until this
```

<Callout type="warn" title="Leave the line out and you get hacker">
  A `mkHaus` call with no `desktop` line selects **hacker**, because every machine
  installed before desktops existed has no such line, and that has always meant
  the developer desktop. The installer writes `desktop = null;` for exactly this
  reason. If you compose your flake by hand and want the foundation, say so.
</Callout>

<Callout title="A desktop you found online is one command, not a hand-edit">
  `haus show github:ada/writer-desktop` fetches it into the store and reports what
  it sets, what it leaves alone and, leaf by leaf, [what would change
  here](/docs/haus/reference/haus#what-would-change-here), including the leaves
  your own host file outranks so the desktop cannot move them at all. It writes
  nothing in your config. `haus add github:ada/writer-desktop` repeats that
  check, then pins and selects it in one edit to `flake.nix` and `flake.lock`, so
  `haus rebuild` is the only step left. `haus desktop` switches and `haus remove`
  unpins. [Share a desktop](/docs/haus/desktops/sharing) and the [CLI
  reference](/docs/haus/reference/haus#pinning-a-desktop-you-found) have all four
  commands in full.
</Callout>

## Changing your mind [#changing-your-mind]

Switch the line, rebuild, and `haus rollback` if you don't like it: a desktop
sets options, and a rebuild computes those from scratch every time. What a
switch does **not** touch is anything outside haus. Files you made, apps you
installed by hand and the macOS settings haus never claimed all stay, and
turning a room off removes what that room installed without tidying up after
you. Homebrew casks a desktop brought in stay on disk too, unless
[`haus.homebrew.cleanup`](/docs/haus/rooms/apps) says otherwise.
