sb is the small CLI inside every copy. Its one job is to run an app on the desktop.
sb run [--json|--quiet] <app> [args…]
What <app> can be #
- A bare name resolves against nixpkgs:
sb run htoprunsnixpkgs#htop,sb run firefoxruns Firefox,sb run xorg.xeyesruns an attribute path. - A flake reference (anything with
#,:or/) is passed through unchanged:sb run github:owner/repo#pkg. - Anything already on
PATHruns directly, without asking Nix at all.
Unfree packages are allowed by default. A copy is a sandbox meant to run anything, Chrome and Slack and Obsidian included.
What happens #
sbrealises the package first, and shows progress. A multi-minute download is visible rather than silent.- It exports the desktop environment (Wayland display, XDG runtime, HiDPI settings, the toolkit backends), because it may be called from a non-login shell.
- It applies a small table of per-app quirks, flags some apps need to behave under this compositor.
- It runs the app. In an interactive terminal the app is in the foreground; when the host calls it, the app is detached and its output is kept in a log inside the copy.
GUI apps appear on the copy's screen. CLI apps run in the terminal.
Where packages come from #
Three layers, all on your Mac's disk, all shared by every copy:
| Layer | Path on the Mac | What it is |
|---|---|---|
| Pull-through cache | nix-cache/ | A caching proxy in front of cache.nixos.org. It never signs anything; it only stores what upstream already signed. |
| Shared store | shared-store/ | The packages themselves, mounted read-only into every copy as the lower layer of its /nix/store. One Firefox on disk, however many copies run it. |
| Guest-built cache | guest-cache/ | Closures a copy had to build itself because nothing upstream had them. The next copy substitutes instead of rebuilding. |
All three live under the app's state directory; see Paths, ports, logs.
The guest image itself stays thin. Baked in: the compositor, sb, a terminal, git, curl, Nix, the GPU tooling. Not baked in: applications. A copy never keeps its own copy of an external package.
Network #
A cold package needs the network: copy → the copy's own user-space NAT → the cache on your Mac → cache.nixos.org. A package that is already in the shared store runs without it.
From an agent #
The sb_run tool types the command into the copy's foreground terminal and presses Return. It launches and does not wait. When the agent needs output back, it uses exec instead.