How to Set Up the OmniRoute Electron Desktop App: Complete Installation Guide
To set up the OmniRoute Electron desktop app, install dependencies in both the root and electron/ directories, then run npm run dev from the electron/ folder to launch the desktop shell with automatic server spawning.
The OmniRoute Electron wrapper transforms the Next.js web application into a native desktop experience. As implemented in diegosouzapw/OmniRoute, this architecture packages a main process that manages windows and server lifecycle, a secure preload script for IPC communication, and React hooks that let the UI interact with native capabilities without compromising Electron security boundaries.
Prerequisites and Repository Structure
Before starting, ensure you have Node.js 18+ and npm installed. The Electron-related code lives entirely within the electron/ directory at the repository root, while the shared React hooks reside in src/shared/hooks/useElectron.ts.
Key directories to understand:
electron/main.js— Main process entry pointelectron/preload.js— Secure renderer bridgeelectron/lib/— Helper utilities for server managementelectron/assets/— Icons and UI resources
Development Setup
The fastest way to run the OmniRoute Electron desktop app locally requires two terminal sessions.
Step 1: Start the Next.js Development Server
# From repository root
npm install
npm run dev
This launches the Next.js dev server (default port 20128). The Electron renderer will poll this endpoint until it responds.
Step 2: Launch the Electron Shell
# In a separate terminal
cd electron
npm install
npm run dev
The npm run dev command in electron/package.json concurrently starts Electron and waits for the server health check at http://localhost:20128. The UI appears only after the server reports ready, preventing blank-screen race conditions.
Production and Stand-alone Builds
For distribution, build the Next.js app in standalone mode so the Electron shell can bundle and spawn it internally.
Build the Next.js Standalone Output
npm run build
This creates a self-contained server under .build/next/standalone/ that the Electron main process references via electron/lib/serverUrlResolver.js.
Run Production Mode
cd electron
npm start
The main process in electron/main.js automatically detects whether to spawn the bundled server or connect to a remote instance based on preferences.
Building Platform-Specific Binaries
Generate installable packages for target operating systems:
cd electron
# Current platform
npm run build
# Windows (.exe installer + portable)
npm run build:win
# macOS (universal .dmg)
npm run build:mac
# Linux (.AppImage)
npm run build:linux
Build artifacts appear in dist-electron/ at the repository root. The electron/package.json scripts delegate to electron-builder with platform-specific configurations.
Remote Server Configuration
The OmniRoute Electron desktop app supports connecting to external OmniRoute instances instead of spawning a local server.
Via Tray Menu
- Right-click the system tray icon
- Select Remote Server → Connect to Remote Server…
- Enter the URL (e.g.,
http://localhost:20128orhttp://10.0.0.5:20128) - Save preferences to
electron-preferences.jsonviaelectron/lib/remoteServerPreferences.js
Via Environment Variable
Override saved preferences for one-off connections:
export OMNIROUTE_REMOTE_URL=http://my-remote-host:20128
cd electron
npm start
The main process checks process.env.OMNIROUTE_REMOTE_URL before consulting persisted preferences, as implemented in the server URL resolution logic.
Security Architecture
The OmniRoute Electron implementation enforces several security best practices:
- Content-Security-Policy — Applied via
session.webRequest.onHeadersReceivedinmain.jsto restrictscript-src,connect-src, and other directives - Context isolation — The preload script uses
contextBridge.exposeInMainWorldwith an explicit whitelist (safeInvoke,safeSend,safeOn) rather than directremotemodule access - IPC cleanup — React hooks like
useServerStatus()andusePortChanged()return disposal functions to prevent listener accumulation
The src/shared/hooks/useElectron.ts file implements useSyncExternalStore for zero-re-render status subscriptions, ensuring efficient UI updates when server state changes.
Troubleshooting Common Issues
| Symptom | Cause | Solution |
|---|---|---|
| Blank window on startup | Server not responding | Verify npm run dev is running in root; check port 20128 availability |
| IPC methods undefined | Preload script failure | Ensure contextIsolation: true in main.js BrowserWindow options |
| Remote connection fails | URL protocol mismatch | Use http:// not https:// for local network addresses |
| Build produces no output | Missing platform dependencies | Install electron-builder prerequisites for target OS |
Summary
- Install dependencies separately in repository root and
electron/directory - Use
npm run devin both locations for development with hot-reload - Build standalone Next.js output with
npm run buildbefore production packaging - Generate binaries with
npm run build:*commands in theelectron/folder - Connect to remote servers via tray menu or
OMNIROUTE_REMOTE_URLenvironment variable - Reference
electron/main.jsfor window lifecycle,electron/preload.jsfor secure IPC, andsrc/shared/hooks/useElectron.tsfor UI integration
Frequently Asked Questions
What Node.js version does OmniRoute Electron require?
OmniRoute builds successfully on Node.js 18 LTS and newer. The electron/package.json specifies compatible Electron versions that bundle their own Node runtime, but development tooling in the root relies on system Node.js for the Next.js build pipeline.
Can I run the desktop app without building the Next.js server first?
For development, yes—run npm run dev in the repository root to start the Next.js dev server, then npm run dev in electron/ to attach the desktop shell. For production, you must run npm run build first to generate the standalone server bundle that electron/main.js spawns.
How does the Electron app know when the server is ready?
The main process polls http://localhost:<PORT> with exponential backoff until receiving an HTTP 200 response. Only then does main.js show the BrowserWindow, implemented in the server health monitoring section. This prevents users from seeing a disconnected UI during cold starts.
Where are remote server preferences stored?
Preferences persist to <userData>/electron-preferences.json via electron/lib/remoteServerPreferences.js, using Electron's app.getPath('userData') directory. The OMNIROUTE_REMOTE_URL environment variable takes precedence over this file for temporary overrides.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →