How to Build and Package the OmniRoute Electron Desktop Application
Run npm run electron:build after npm run build to compile native modules and produce platform-specific installers in ./dist/.
The OmniRoute Electron desktop application bundles the same routing engine as the web API into a cross-platform desktop client. According to the OmniRoute source code, the build pipeline uses a three-phase approach: preparing a standalone Node runtime, rebuilding native dependencies for Electron's ABI, and packaging with electron-builder.
Prerequisites and Initial Setup
Before building the Electron app, you need to install dependencies and build the web UI bundle.
# Install all development dependencies
npm ci
# Build the production web UI (required before Electron packaging)
npm run build
The web bundle must exist because electron/main.js serves it through the bundled server in standalone mode.
The Three-Phase Build Pipeline
Phase 1: Prepare the Standalone Node Runtime
Electron requires native modules compiled against its specific Node version. The script at scripts/build/prepare-electron-standalone.mjs creates a clean ./.build/electron-standalone tree containing the exact Node version used by Electron.
This isolated runtime ensures that modules like better-sqlite3 are available in a version-matched environment separate from your development Node installation.
Phase 2: Rebuild Native Dependencies for Electron
Native addons must be compiled against Electron's ABI, not your system Node. The helper scripts/build/electronRebuildPlan.mjs analyzes electron/package.json and generates the correct npm rebuild calls.
This step is automatically invoked by the npm scripts—you don't need to run it manually.
Phase 3: Package with electron-builder
The final installers are produced by electron-builder, configured in the build section of electron/package.json. This configuration defines:
- Output formats:
nsis(Windows installer),dmg(macOS),zip,AppImage(Linux) - Extra resources: The compiled runtime from Phase 1
- File whitelist: What ships in the final ASAR archive
npm Scripts for Development and Production
| Script | What It Does |
|---|---|
npm run electron:dev |
Launches hot-reloading development instance; watches src/ and open-sse/ for changes |
npm run electron:build |
Full production pipeline: runtime prep, native rebuild, and electron-builder packaging |
npm run electron:release |
Triggers GitHub Actions workflow at .github/workflows/electron-release.yml for signed releases |
The electron:release script publishes binaries and generates latest-*.yml update manifests consumed by the built-in auto-updater.
Complete Build Example
# One-time setup
npm ci
npm run build
# Package the desktop application
npm run electron:build
# Installers appear in ./dist/
# • Windows: OmniRoute-Setup-*.exe (NSIS)
# • macOS: OmniRoute-*.dmg
# • Linux: OmniRoute-*.AppImage
For iterative UI development with hot-module replacement:
npm run electron:dev
Key Implementation Files
Understanding these source files helps when customizing the build:
Main Process Entry Point
electron/main.js bootstraps the UI, configures the IPC bridge via preload.js, starts the OmniRoute server in standalone mode, and registers the autoUpdater from electron-updater.
Preload Script Security
electron/preload.js exposes a safe electronAPI to the renderer process, forwarding requests to the bundled server via fetch. This isolated context prevents direct Node access from renderer code.
electron-builder Configuration
The electron/package.json build object controls packaging:
// Key configuration concepts from electron/package.json
{
"build": {
"extraResources": [
// Copies ../.build/electron-standalone/node_modules into packaged app
],
"files": [
// Whitelist of files included in final ASAR
// CI test suite enforces completeness
]
}
}
SQLite Utilities
electron/sqlite-inspection.js verifies local database integrity and handles schema migrations for the desktop client's bundled SQLite database.
Verification and Testing
The test file tests/unit/electron-main.test.ts enforces packaging correctness. It asserts that every dependency referenced by source code appears in build.files, preventing runtime "module not found" errors that only surface in packaged builds.
Summary
- Always run
npm run buildbeforenpm run electron:build— the Electron app serves the web bundle - Native modules require ABI-specific compilation — handled automatically by
prepare-electron-standalone.mjsandelectronRebuildPlan.mjs - Packaging configuration lives in
electron/package.json— controls installers, extra resources, and ASAR contents - Use
electron:devfor live-reload development andelectron:releasefor CI-driven distribution - The auto-updater relies on
latest-*.ymlmanifests published by the GitHub Actions workflow
Frequently Asked Questions
What Node version does OmniRoute Electron target?
The build system determines this automatically. The prepare-electron-standalone.mjs script extracts Electron's embedded Node version and creates an isolated runtime at ./.build/electron-standalone. You don't need to manage Node versions manually.
Why does the build fail with "native module version mismatch"?
This occurs when native modules like better-sqlite3 are compiled for your system Node instead of Electron's ABI. Run npm run electron:build rather than manual rebuilds—it invokes electronRebuildPlan.mjs to generate correct compiler flags.
Can I customize which installer formats are generated?
Yes. Edit the build object in electron/package.json. Add or remove targets from the platform-specific configuration. Common options include nsis and zip for Windows, dmg and zip for macOS, and AppImage or deb for Linux.
How does the auto-updater work in packaged builds?
electron/main.js registers autoUpdater from electron-updater. The release workflow publishes version metadata as latest-*.yml files. The running client polls these manifests and prompts users when updates are available, downloading and installing them automatically.
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 →