docs/ops/SQLITE_RUNTIME.md
OmniRoute resolves its SQLite driver at startup through a 5-step fallback chain:
Bundled better-sqlite3 (via dependencies in package.json)
— fastest, native binary, installed by npm install when build tools are present.
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.
node:sqlite (Node ≥22.5 stdlib) — no native build needed; used when
both better-sqlite3 paths fail. Limited feature set.
sql.js (WASM) — final fallback. Works everywhere but is slower
and writes data on an interval rather than synchronously.
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.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.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" }
# 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 helpersbin/cli/runtime/sqliteRuntime.mjs — 5-step runtime resolver + lazy installerbin/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