Configuration
The generated config.desktop block - every field, where the committed module lives, and the one per-environment backend URL.
Scaffolding with --desktop emits a config.desktop block (typed by DesktopConfig), derived from your app name and base URL at init. Examples below assume an app named Acme on acme.com.
Fields
| Field | Example | Description |
|---|---|---|
enabled | true | Whether the desktop app ships with this project. |
appId | com.acme.acme | Reverse-DNS application id - the installer id plus the Windows AppUserModelID. Leading labels come from the base-URL domain reversed (acme.com -> com.acme); the last segment is the protocol slug with hyphens removed. |
productName | Acme | Display name for the window title and installer. |
protocol | acme | Custom deep-link URL scheme without ://, a slug of the app name. |
baseUrl | https://acme.com | Web app origin the app targets in production builds, and the default backend API origin when no BASE_URL / PUBLIC_API_URL is set. |
supportChat | true | Whether the live-chat widget from config.support also mounts in the app. false keeps live chat on your website only - the app mounts no widget and its CSP never names the provider's origins. |
autoUpdate.url | https://cdn.acme.com/desktop | Public base URL of the update feed and download links. electron-updater polls <url>/latest-mac.yml (macOS), <url>/latest.yml (Windows), <url>/latest-linux.yml (Linux). |
agents | see AI agents | The desktop AI feature flags. |
Review the derived appId and protocol. Pure-digit or non-ASCII app names produce odd slugs - a URL scheme cannot start with a digit, and accents are dropped - so edit packages/config/src/desktop.mjs by hand for such names.
Where the block lives
The values live in a committed plain-JS module, packages/config/src/desktop.mjs, exported as @repo/config/desktop. The Electron bundles, the CSP policy builder, and the electron-builder packaging config all import it directly, because none of them can import the env-reading @repo/config index.
- Committed, not env: the values are identical in dev and production. Edit the module once (or re-run the CLI) to rebrand the app name, id, scheme, and update feed everywhere.
- One identity: electron-builder reads the same module for the installer's
appId,productName, deep-link scheme, and update feed, so the installer and the running app can never disagree. - Backend follows
baseUrl:apps/desktop/src/main/backend-url.tspins every bridged request to that origin, so changing it repoints the app with no hand-edit.
Backend URL per environment
The backend URL is the one per-environment value. Set it with env when you run or build; otherwise it defaults to config.desktop.baseUrl for a build and the local web app in dev.
| Env var | Used for |
|---|---|
BASE_URL | Web app origin. Overrides config.desktop.baseUrl; in dev it comes from the root .env. |
PUBLIC_API_URL | Hosted backend API URL (defaults to ${BASE_URL}/api). |
The renderer's CSP connect-src names no backend origin - every backend call rides the main-process bridge, not the renderer's network. See Sign-in and security.
Desktop app
The cross-platform Electron desktop app gated by config.desktop - what it ships, how to enable it, and how AI and billing behave inside it.
Sign-in and security
Device authorization sign-in for the desktop app plus the shell's security boundaries - CSP, navigation, the preload bridge, and the OS keychain.