Configuration
How the --desktop flag maps to the generated config.desktop block, its fields, and the per-environment backend URL.
Configuration (config.desktop)
When scaffolded with --desktop, @repo/config 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.
| 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. The domain part is the base-URL domain reversed (acme.com -> com.acme); the last segment is a slug of the app name. |
productName | Acme | Display name for the window title and installer (your app name). |
protocol | acme | Custom deep-link URL scheme without ://, a slug of the app name. |
baseUrl | https://acme.com | Web app origin the desktop targets in production builds - the default backend API origin (backend-url.ts pins every bridged request to it) when no BASE_URL/PUBLIC_API_URL env is set. |
dataFolder | data | Folder name for the app's persisted files (logs, AI-agent data, generated artifacts), created under the OS app-data dir. Rename at will. |
autoUpdate.url | https://cdn.acme.com/desktop | Base URL of the update feed and download links - your public storage bucket's domain plus a path prefix (where the release publishes installers, the latest*.yml feeds, and the per-installer .blockmap files). electron-updater polls <url>/latest-mac.yml (macOS), <url>/latest.yml (Windows), and <url>/latest-linux.yml (Linux). |
How appId and protocol derive:
- Leading reverse-DNS labels of
appId: from the base URL. - Last segment of
appId: theprotocolslug with hyphens removed (reverse-DNS labels avoid hyphens). protocol: a slug of the app name.
Where it lives: the Electron main and renderer bundles, the CSP policy builder, and the electron-builder packaging config cannot import the env-reading @repo/config index, so config.desktop lives in a committed plain-JS module - packages/config/src/desktop.mjs, exported as @repo/config/desktop - that they all import directly.
Committed config, not env: these values are identical in dev and production. Edit desktop.mjs once (or re-run the CLI) to rebrand the app name, id, scheme, and update feed everywhere. electron-builder reads the same module for the installer's appId, productName, deep-link scheme, and update feed, and the app reads it for the window title and its own identity - so there is no separate sync step and the installer and running app can never disagree. The backend target follows it automatically too: backend-url.ts pins every bridged backend request to the origin from config.desktop.baseUrl (or BASE_URL/PUBLIC_API_URL), so changing baseUrl repoints the app's backend with no hand-edit. The renderer's CSP connect-src names no backend origin - every backend call rides the main-process bridge, not the renderer's network (see Security).
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 derived appId and protocol are sensible defaults you should review. 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.