Self-hosting
The Expanse desktop app runs fully on its own, with your workbooks as local files. You only need a backend if you want hosted sync and collaboration on your own infrastructure (a laptop, a single VPS, your private cloud, or air-gapped behind a firewall).
For the full reference, see
SELF_HOSTING.md
in the repository. This page is the short version.
What runs
Section titled “What runs”docker compose up brings up three services on one host:
- postgres: Postgres 17, holding users, organizations, and sessions.
- auth: a Bun runtime running BetterAuth (the same handler as the hosted Cloudflare deployment), on port 3000.
- collab: the Rust collab server (
expanse-collab-server), a WebSocket endpoint for real-time sheet sync on port 8787. It validates each connection against the auth service.
Quickstart
Section titled “Quickstart”git clone https://github.com/fruit-cards/expansecd expansecp .env.example .env # fill in a BetterAuth secret and an OAuth providerjust self-host-up # docker compose up -d --buildUseful recipes: just self-host-logs, just self-host-down (keeps the
database volume), just self-host-down-clean (drops it).
Connecting the desktop app
Section titled “Connecting the desktop app”Point the desktop client at your server with two environment variables:
EXPANSE_COLLAB_URL: the WebSocket URL of your collab server, for examplews://your-host:8787/sheet/<workbook-uuid>. Unset or empty means the app stays fully local (no sync).EXPANSE_COLLAB_TOKEN: a bearer token from signing in to the auth service.
License tiers
Section titled “License tiers”The EXPANSE_LICENSE_KEY variable selects the tier:
- Trial: empty or unset. All features unrestricted.
- Self-host paid: any non-empty value. Same as trial today; get a key from Polar when you want a long-term license.
Do not set EXPANSE_HOSTED=1 on a self-host deployment; that is reserved for
the hosted offering and turns on usage metering.
What works today, and what doesn’t
Section titled “What works today, and what doesn’t”Self-hosting is usable for personal use and small teams. Be aware that:
- Sync currently covers a single sheet per workbook.
- The collab server keeps room state in memory, so an in-progress session resets if the server restarts. Your workbook files are unaffected.
- There is no per-seat metering or billing in self-host; every feature is on.
The desktop app itself works fully offline regardless, so none of this is required just to use Expanse. See Collaboration for what the sync actually does.