Skip to content

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

bash
# 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:desktop

How It Works

EnvironmentOperational Logic
DevelopmentBridges the Electron shell with the Vite Dev Server, enabling Hot Module Replacement (HMR) and real-time UI synchronization at http://localhost:5173.
ProductionOrchestrates 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.json

Scripts

Development & Build

ScriptDescription
pnpm devLaunch the electron-vite development server with live reload
pnpm buildCompile main, preload, and renderer TypeScript modules → out/
pnpm prebuildSynchronize 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 previewPreview 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:

CommandPlatformOutput Artifact
pnpm packageCurrent OSDetects host OS and builds accordingly
pnpm package:macmacOS.dmg and .zip (supports x64 & arm64)
pnpm package:winWindows.exe (NSIS Installer)
pnpm package:linuxLinux.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:

bash
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:

yaml
strategy:
  matrix:
    os: [macos-latest, windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}

Configuration

The target web application is configured via .env:

env
DESKTOP_TARGET_APP=web
DESKTOP_DEV_SERVER_URL=http://localhost:5173

See 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.

SettingValuePurpose
contextIsolationtruePreload executes in a hermetically sealed JavaScript context
nodeIntegrationfalseZero Node.js API surface exposed to the renderer
sandboxtrueChromium OS-level sandbox enforced
webSecuritytrueSame-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 the web-dist/ boundary using normalize() + startsWith(). Traversal attempts like app://-/../../etc/passwd are met with 403 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 Sanitizationsession.defaultSession.webRequest intercepts all outgoing requests, stripping app:// / file:// Origin headers to prevent backend CORS rejections.
  • Navigation Guard — The will-navigate event intercepts and blocks all navigation attempts to URLs outside the app:// 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

DocumentScope
CONFIGURATION.mdTarget app switching, app:// protocol internals, HashRouter fallback procedure
AUTO_UPDATER.mdRelease lifecycle, CI/CD variables, provider switching, code signing
IPC_ARCHITECTURE.mdSecurity model, Three-Step Bridge pattern, existing IPC channels, extensibility guide