Desktop
Architectural Foundation: Electron · electron-vite · electron-builder · electron-updater
Description: Secure Electron desktop wrapper that embeds monorepo web applications, providing custom app:// protocol routing, hardware IPC bridge, auto-updates, and CORS bypass proxy with hardened security defaults.
The native gateway for our monorepo applications.
This package serves as a secure, high-performance Electron wrapper that transforms our web-based assets into first-class desktop experiences. Built on top of electron-vite for near-instant development cycles and electron-builder for seamless cross-platform distribution.
Quick Start
# From the monorepo root
# Install dependencies
pnpm install
# Development (starts both the web dev server and Electron)
pnpm dev:desktop
# Build for production
pnpm build:desktop
# Package for distribution
pnpm package:desktopHow It Works
| Environment | Operational Logic |
|---|---|
| Development | Bridges the Electron shell with the Vite Dev Server, enabling Hot Module Replacement (HMR) and real-time UI synchronization at http://localhost:5173. |
| Production | Orchestrates a Secure Custom Protocol (app://) to serve optimized static assets, ensuring seamless SPA client-side routing via an intelligent index.html fallback mechanism. |
Project Structure
apps/desktop/
├── docs/ # Architecture & Operations Documentation
│ ├── CONFIGURATION.md # Target app switching, routing fallback procedures
│ ├── AUTO_UPDATER.md # Release lifecycle, CI/CD, code signing
│ └── IPC_ARCHITECTURE.md # Security model, extensibility patterns
├── scripts/
│ └── copy-web-dist.ts # Prebuild bridge: syncs web build → web-dist/
├── src/
│ ├── main/
│ │ └── index.ts # Main process: protocol, CORS, IPC, updater
│ ├── preload/
│ │ └── index.ts # Secure contextBridge API surface
│ └── renderer/
│ └── index.html # Renderer shell
├── .env # Runtime configuration
├── electron-builder.yml # Packaging & auto-update provider config
├── electron-vite.config.ts # Three-target build config (main, preload, renderer)
├── package.json
├── tsconfig.json
├── tsconfig.main.json
├── tsconfig.preload.json
└── tsconfig.renderer.jsonScripts
Development & Build
| Script | Description |
|---|---|
pnpm dev | Launch the electron-vite development server with live reload |
pnpm build | Compile main, preload, and renderer TypeScript modules → out/ |
pnpm prebuild | Synchronize the target web app's build output via scripts/copy-web-dist.ts — copies apps/<DESKTOP_TARGET_APP>/dist/ → web-dist/. Invoked automatically before pnpm build. |
pnpm preview | Preview the compiled Electron app locally without generating a distributable |
🚀 Packaging & Distribution
To generate a production-ready installer, execute from within apps/desktop/ or use the root-level pnpm package:* commands, which orchestrate the full pipeline automatically:
| Command | Platform | Output Artifact |
|---|---|---|
pnpm package | Current OS | Detects host OS and builds accordingly |
pnpm package:mac | macOS | .dmg and .zip (supports x64 & arm64) |
pnpm package:win | Windows | .exe (NSIS Installer) |
pnpm package:linux | Linux | .AppImage |
All artifacts are emitted to the release/ directory.
> **Deterministic Build Pipeline**: All `package:*` commands strictly enforce a deterministic build pipeline: compiling web assets via Turborepo, synchronizing the output via the `prebuild` bridge (`node --import tsx scripts/copy-web-dist.ts`), and finally generating the native binary through `electron-builder`.
Running locally within apps/desktop/: These scripts assume the web app has already been compiled. Either run pnpm build --filter=web beforehand, or use the root-level pnpm package:* commands which handle the complete orchestration.
> **macOS Code Signing**: Distributable macOS builds with Auto-Update capability **require** an Apple Developer Certificate. Provide the following environment variables:
CSC_LINK=<base64-encoded .p12 certificate>
CSC_KEY_PASSWORD=<certificate password>
APPLE_ID=<your apple id>
APPLE_APP_SPECIFIC_PASSWORD=<app-specific password>
APPLE_TEAM_ID=<team id>Without valid code signing, macOS Gatekeeper will quarantine the application and electron-updater will reject update payloads. See AUTO_UPDATER.md for the complete requirements.
> **Cross-Compilation Advisory**: It is strongly recommended to build for each platform on its native OS. Cross-compilation (e.g., producing `.dmg` on Linux) may fail due to platform-specific toolchain dependencies. For CI, leverage a matrix strategy:
strategy:
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}Configuration
The target web application is configured via .env:
DESKTOP_TARGET_APP=web
DESKTOP_DEV_SERVER_URL=http://localhost:5173See CONFIGURATION.md for comprehensive guidance on target app switching, protocol internals, and the HashRouter fallback procedure.
Core Capabilities
🌐 Custom app:// Protocol
Provides a secure file-serving layer with built-in Path Traversal Protection and automated CSP Header Injection. All requests to unknown paths are intelligently rerouted to index.html, enabling React Router to resolve routes client-side without blank screens or 404 errors.
🖨️ Hardware Bridge
Enables granular control over system peripherals — such as printers — through an asynchronous IPC communication layer. The React app can enumerate connected printers and dispatch print jobs via window.electronAPI.getPrinters() and window.electronAPI.print(), all without exposing native APIs to the renderer.
🔄 Auto-Update Engine
A fully managed update lifecycle powered by electron-updater. Background download progress is forwarded in real-time to the React UI via IPC event subscriptions, enabling rich notification experiences. See AUTO_UPDATER.md.
🛡️ CORS Bypass Proxy
A transparent proxy mechanism that handles cross-origin requests by sanitizing non-standard app:// and file:// Origin headers on outgoing requests and injecting permissive CORS response headers on incoming responses — allowing seamless integration with cloud APIs without server-side configuration changes.
🔒 Single Instance Lock & Data Integrity
The application enforces a single running instance via app.requestSingleInstanceLock(). If a user attempts to launch a second instance, the duplicate process is terminated immediately and the existing window is restored and focused. This mechanism serves two critical purposes:
- Data Integrity: Prevents race conditions and write conflicts in local databases (IndexedDB/PouchDB) that could arise from concurrent access by multiple Electron processes.
- Resource Efficiency: Avoids duplicate memory allocation, IPC handler registration, and protocol handler conflicts.
Hardened Security Perimeter
The Desktop Wrapper enforces a hardened security perimeter, strictly isolating the Node.js Main Process from the Renderer Context. Our architecture is built upon the principle of Least Privilege, ensuring that the web application only interacts with system hardware through a verified, secure IPC bridge.
| Setting | Value | Purpose |
|---|---|---|
contextIsolation | true | Preload executes in a hermetically sealed JavaScript context |
nodeIntegration | false | Zero Node.js API surface exposed to the renderer |
sandbox | true | Chromium OS-level sandbox enforced |
webSecurity | true | Same-origin policy strictly upheld |
Defense-in-depth protections in src/main/index.ts:
- Path Traversal Guard — The
app://protocol handler validates all resolved file paths remain within theweb-dist/boundary usingnormalize()+startsWith(). Traversal attempts likeapp://-/../../etc/passwdare met with403 Forbidden. - CSP Header Injection — Content-Security-Policy headers are injected as HTTP response headers on every HTML response served by the custom protocol — not via a
<meta>tag — ensuring they cannot be stripped or bypassed by injected scripts. - Origin Sanitization —
session.defaultSession.webRequestintercepts all outgoing requests, strippingapp:///file://Origin headers to prevent backend CORS rejections. - Navigation Guard — The
will-navigateevent intercepts and blocks all navigation attempts to URLs outside theapp://protocol and the authorized dev server origin.
See IPC_ARCHITECTURE.md for the full security model, the Three-Step Bridge pattern, and guidance on safely extending the app with new native features.
Documentation
| Document | Scope |
|---|---|
| CONFIGURATION.md | Target app switching, app:// protocol internals, HashRouter fallback procedure |
| AUTO_UPDATER.md | Release lifecycle, CI/CD variables, provider switching, code signing |
| IPC_ARCHITECTURE.md | Security model, Three-Step Bridge pattern, existing IPC channels, extensibility guide |