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 build before npm run electron:build — the Electron app serves the web bundle
  • Native modules require ABI-specific compilation — handled automatically by prepare-electron-standalone.mjs and electronRebuildPlan.mjs
  • Packaging configuration lives in electron/package.json — controls installers, extra resources, and ASAR contents
  • Use electron:dev for live-reload development and electron:release for CI-driven distribution
  • The auto-updater relies on latest-*.yml manifests 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →