Skip to content

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.

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.
Terminal window
git clone https://github.com/fruit-cards/expanse
cd expanse
cp .env.example .env # fill in a BetterAuth secret and an OAuth provider
just self-host-up # docker compose up -d --build

Useful recipes: just self-host-logs, just self-host-down (keeps the database volume), just self-host-down-clean (drops it).

Point the desktop client at your server with two environment variables:

  • EXPANSE_COLLAB_URL: the WebSocket URL of your collab server, for example ws://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.

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.

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.