# Share a desktop (/docs/haus/desktops/sharing)



A desktop is one readable file, so sharing one is mostly about being honest in
the README, which is the part the format can't check for you.

## Publish something inspectable [#publish-something-inspectable]

The smallest useful repository is deliberately boring:

```text
writer-desktop/
├── README.md
├── writer.nix
└── LICENSE
```

Tell people they can read it before they run it: `haus show
github:you/writer-desktop` fetches it into the store and reports on it without
touching their config. Once they trust it, `haus add github:you/writer-desktop`
pins and selects it in one edit, and `haus rebuild` is the only step left. That
is the [CLI reference](/docs/haus/reference/haus#pinning-a-desktop-you-found)'s
job to teach, not your README's.

<Callout title="Vendoring is still there for a one-off">
  `haus add --vendor github:you/writer-desktop` copies the file into their config
  at `desktops/writer.nix` instead of pinning it, for someone who plans to fork it
  immediately. It stages the file too, which a hand copy has to do for itself: Nix
  reads only a config's tracked files, and neither `haus show` nor `checkDesktop`
  catches a missing `git add`, because both read what they are handed and pass on
  the very file the rebuild cannot see.
</Callout>

A flake wrapper can come later if versioned imports turn out to be useful. It
should not hide the data people are being asked to trust, and any wrapper owes
every module it rebuilds a `_file`, or the conflicts it causes name no file at
all.

## What the README owes a reader [#what-the-readme-owes-a-reader]

Someone deciding whether to run your desktop is deciding what their Mac will feel
like tomorrow. Tell them:

* **who it's for**: the kind of person or the kind of work, in a sentence;
* **which rooms it turns on, and which it deliberately leaves off**, with the
  reason for the off ones, which is the part they cannot reconstruct from the
  file;
* **the strong opinions**: a claimed global hotkey, a remapped Caps Lock, a
  changed default browser, anything that will surprise muscle memory;
* **which haus revision you tested against**;
* **what it deliberately doesn't handle**: permissions it expects them to grant,
  hardware it assumes, apps it doesn't install;
* **any list-typed option it sets** (`tour.steps`, `keys.leaderExtras`,
  `snippets.matches`), because a host that names the same one [replaces yours
  whole](/docs/haus/desktops/creating#leave-room-for-the-host);
* **that both `haus show` and a real host evaluation passed**.

You do not need to document how to override you: a host beats a desktop with a
plain assignment, every time.

## A room is the neighbouring format [#a-room-is-the-neighbouring-format]

The other thing you can publish is a **room**: *code* where a desktop is data, an
ordinary nix-darwin module exported under `darwinModules`, free to install
packages, write files and run activation steps as root. `haus show` says so and
checks nothing, which is the honest answer rather than a gap in the tooling.

So a *set of apps* rather than a whole machine is a room:
`haus.photography.enable` bringing the apps and whatever else that capability
needs. A machine runs one desktop and as many rooms as it likes. A published room
claims a plain `haus.<name>`, since `haus.my.*` is reserved for rooms that never
leave one Mac: `haus add --room --namespace <ns>` records who claimed the name,
and a namespace nobody has claimed warns once per rebuild that nothing says where
it came from. [Share a room](/docs/haus/rooms/sharing) is the rest of it.

<Callout type="info" title="There is no third format: app packs do not exist">
  `haus.lib.pack`, `checkPack`, `haus.packFiles` and `haus.packs` are not options.
  If a config you are reading names one, delete the line. The collections haus
  itself ships are a different thing and are unaffected, still one line each
  (`haus.apps.packs.writing.enable = true`).
</Callout>

## Before you share [#before-you-share]

* [ ] `haus show ./writer.nix` passes, and a real host evaluates.
* [ ] You have run it on a Mac, not only evaluated it.
* [ ] Every room it turns off agrees with the features that depend on that room,
  `tour.steps` included.
* [ ] The README says everything above, list-typed options included.
* [ ] There is no identity, secret or device-specific data anywhere in it.
