Download
Grab the latest release:
Download the latest release, install dependencies, and get Spaces running on your Mac, plus the daemon on any Linux machine you want to work on and what a remote machine or cloud VM needs before it can pair.
Grab the latest release:
Install Spaces in the DMG.Spaces.app, links the required spaces CLI and spacesd daemon helpers to the app bundle, and sets up the per-user background service (LaunchAgent) that keeps your terminal sessions alive.Spaces relies on Google Chrome for browser sessions. Install it before launching.
brew install --cask google-chrome.Spaces includes its own terminal, so workspaces do not depend on any external terminal app.
Confirm the CLI and GUI are working:
spaces --version
open -a SpacesThe first command prints the installed version. The second launches the app.
Spaces checks for updates automatically through its built-in updater, and you can also check manually from the app menu. New versions install in place. Manual DMG downloads stay available on the releases page if you prefer to update by hand.
To remove Spaces completely:
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/dev.usespaces.spacesd.plist
rm -f ~/Library/LaunchAgents/dev.usespaces.spacesd.plist
rm -rf /Applications/Spaces.app
rm -f /usr/local/bin/spaces /usr/local/bin/spacesd /usr/local/bin/spaces-caddy
rm -f ~/.spaces/bin/spaces ~/.spaces/bin/spacesd
rm -rf ~/.spaces ~/spaces~/.spaces holds Spaces's local database; ~/spaces holds any git repos Spaces cloned for you and its workspace worktrees. Leave them alone if you want to keep that state.
Install the Spaces daemon on a Linux machine to run workspaces there and drive them from your Mac or iPhone. Ubuntu 24.04 on x86_64 or arm64 is supported. Pairing a Linux machine that does not have Spaces installed installs it as part of connecting: the pairing screen runs the installer over the same SSH connection, shows its progress until it finishes (usually a few minutes), and pairs automatically once it does. You can also run the installer on the machine yourself first, which pairing then uses directly.
On the Linux machine, install the latest release:
curl -fsSL https://usespaces.dev/install.sh | bashTo pin a specific release, pass its version — replacing <version> with a released version such as 0.1.0:
curl -fsSL https://usespaces.dev/install.sh | bash -s -- <version>The Mac app and the spaces CLI print the version-pinned command with the right version already filled in whenever they reach a Linux machine whose daemon is missing or out of date. Released versions are listed on the releases page.
The installer checks the download against the signed release before running it, then:
~/.spaces and puts the spaces CLI on your PATH at ~/.local/bin/spaces.spacesd.service as a systemd user service and starts it. The service keeps running after you disconnect, so your terminal sessions survive closing SSH.47847, which the devices you pair from need to reach — see Remote Machines & Cloud VMs below.It needs curl, tar, sha256sum, openssl, and python3. If it can't keep background services running for your account on its own, it stops and tells you to run sudo loginctl enable-linger $USER and try again.
Once the daemon is running, pair the machine with your Mac or iPhone. See the CLI reference for spaces device pair.
Re-run the same command with the new version to update in place. There is no separate update command: it hands the running daemon over to the new version without a full restart, so your terminal sessions, processes, and coding agents keep running across the update.
The Mac app also keeps track of whether a machine's daemon is behind. If a newer version is already on the machine, the app puts it in place on its own, with nothing running there interrupted; if that doesn't land within a bit, the app says so and offers to try again. If nothing newer is installed yet and the machine was paired over SSH, the app offers an Update over SSH action that runs the same update over that connection for you — terminals, processes, and coding agents keep running throughout. The command above stays available if you'd rather run it by hand, and it's the only option for a machine paired from a link instead of over SSH.
A client and a daemon can only talk to each other when they speak the same protocol, and Spaces will not connect them when they don't. When that happens Spaces tells you which side is behind: update the Mac app through its built-in updater, or update the Linux daemon as described above.
On the Linux machine:
systemctl --user disable --now spacesd.service
rm -f ~/.config/systemd/user/spacesd.service
systemctl --user daemon-reload
rm -f ~/.local/bin/spaces
rm -rf ~/.spaces ~/spacesAs on macOS, ~/.spaces holds the daemon's local database and ~/spaces holds its repos and workspace worktrees. Leave them alone if you want to keep that state.
A machine you want to work on from your Mac or iPhone — a Linux box under your desk, a cloud VM, or a second Mac — has to meet a few requirements before it can pair. Set them up first and pairing goes through on the first attempt.
Pairing connects two Spaces installs, so the machine needs its own. A Linux machine needs the daemon on Ubuntu 24.04 (x86_64 or arm64); pairing installs it automatically over SSH if it isn't there yet, or you can run the installer yourself first — both covered under Linux above. A second Mac needs Spaces.app installed and opened once, exactly like the Mac in front of you.
known_hosts. Connecting to it once by hand — ssh user@host — records the key and is enough. If that host key changes later, on a rebuilt VM for example, pairing fails until you replace the stale known_hosts entry.Pairing itself rides SSH, but nothing after it does: once paired, your Mac or iPhone talks to the machine's Spaces daemon on TCP 47847. That port has to be reachable from the client over whatever network you use — LAN, VPN, or Tailscale.
On a cloud VM that means an ingress firewall rule allowing tcp:47847 from the addresses you connect from, alongside the rule for SSH (tcp:22 unless you moved it). Reaching the machine at its tailnet address rather than its public address needs no ingress rule at all.
This is the failure worth recognizing, because working SSH makes it look like the network is fine: pairing gets all the way through the SSH step, and then Spaces reports that the remote Device API is not reachable at that address and port. Open the port and pair again.
The daemon keeps workspaces, terminals, and coding agents running on the machine after your SSH session ends, which the machine has to allow for your account. The Linux installer arranges that for you; if it can't, it stops and prints the one command to run on the machine before you install again (see Linux above). On a Mac, the background service the installer sets up already covers it.
A client and a machine also have to run matching Spaces versions before they will connect at all — see Update under Linux above.