Skip to content
OmniRoute source

SQLite Runtime Resolution

OmniRoute resolves its SQLite driver at startup through a 5-step fallback chain:

  1. Bundled better-sqlite3 (via dependencies in package.json) — fastest, native binary, installed by npm install when build tools are present.

  2. Runtime-installed better-sqlite3 (in ~/.omniroute/runtime/) — installed lazily on first run OR by scripts/build/postinstall.mjs → scripts/postinstall.mjs. Validates native .node magic bytes (ELF / Mach-O / PE) before loading to guard against corrupt or wrong-platform binaries.

  3. node:sqlite (Node ≥22.5 stdlib) — no native build needed; used when both better-sqlite3 paths fail. Limited feature set.

  4. sql.js (WASM) — final fallback. Works everywhere but is slower and writes data on an interval rather than synchronously.

  • Windows EBUSY: npm install -g omniroute@latest can fail if the previous version’s better_sqlite3.node is locked by a running process. The runtime install in ~/.omniroute/runtime/ sidesteps the global npm cache.
  • No build tools: Some environments (corporate Windows without VS Build Tools, minimal Docker images) cannot compile better-sqlite3. The runtime installer resolves a pre-built binary from the npm registry; the fallback drivers ensure OmniRoute still boots even if that fails.
  • Air-gapped systems: If the npm registry is unreachable, node:sqlite or sql.js guarantee baseline functionality.

Before loading a runtime-installed .node file, OmniRoute reads the first 8 bytes and matches against known platform magics:

Platform Bytes (hex) Label
Linux 7F 45 4C 46 elf
macOS 64-bit BE FE ED FA CF macho
macOS 64-bit LE CF FA ED FE macho-le
macOS fat (universal) CA FE BA BE macho-fat
Windows 4D 5A (MZ) pe

A mismatched magic → file is ignored, fallback continues to the next step.

import { getDriverInfo } from "@/lib/db/core";
const info = getDriverInfo();
// { source: "bundled" | "runtime" | "runtime-installed-now" | "node-sqlite" | "sql-js",
// kind: "better-sqlite3" | "node-sqlite" | "sql-js" }
Terminal window
# Skip postinstall warm-up (for fast CI installs)
OMNIROUTE_SKIP_POSTINSTALL=1 npm install -g omniroute
# Force-reinstall runtime better-sqlite3
rm -rf ~/.omniroute/runtime
omniroute # will reinstall on next start
# Check what driver is active
omniroute config db-info # (if CLI command exists)

Implementation:

  • bin/cli/runtime/magicBytes.mjs — binary magic-byte validation helpers
  • bin/cli/runtime/sqliteRuntime.mjs — 5-step runtime resolver + lazy installer
  • bin/cli/runtime/index.mjs — startup orchestrator (warmUpRuntimes())
  • scripts/postinstall.mjs — npm post-install hook (non-fatal warm-up)
  • src/lib/db/core.ts — ensureDbInitialized() / getDriverInfo() exports

The driver fallback chain above still runs in one process. Default SQLite OmniRoute is a single writer:

  • Do not attach two OmniRoute replicas to the same storage.sqlite file.
  • A container restart, Recreate deploy, OOM kill, or HEALTHCHECK restart drops every in-flight SSE session. There is no session drain on the stock path.
  • Orchestrator liveness that treats a slow /healthz as dead will kill the only replica. Prefer TCP liveness + HTTP /healthz readiness. See Docker Guide — availability and Kubernetes probe recommendations.

OmniRoute source repository (a58000c7685f)

HagiCode

HagiCode is an agentic coding workspace: structured workflows, multi-agent execution, and Hero Dungeon views turn ideas into shipped software.

Turn ideas into polished, usable software with a smarter, faster, and more enjoyable agentic coding workflow.

HagiCode light theme main interface screenshot
  • SmartStructured workflows turn intent into an executable path from idea to shipped change.
  • EfficientMulti-agent workflows keep research, implementation, and review moving in parallel.
  • FunHero Dungeon interfaces make long coding sessions visual, collaborative, and rewarding.
Visit HagiCode