Native addons (N-API)
Owear does not embed its own Node engine. The main process runs on a real
Node resolved by the Runtime Manager (app.ensureNodeRuntime()), with priority
OW_NODE_BIN → system Node → Owear cache → official download. That is why N-API
addons work with no compatibility layer.
What works as-is
- Addons built with N-API (
node-addon-api,napi-rs,prebuildify): the ABI is stable across Node versions, so they load without rebuilding. - Packages that ship Node prebuilds — most do:
better-sqlite3,sharp,sqlite3,keytar, and so on. - Standard Node built-ins:
child_process,worker_threads,net,crypto,fs, and the rest. - Owear workers (
app.forkWorker) run on the same Node, so they can load addons too.
What does not work without a rebuild
Binaries precompiled for Electron (what
electron-rebuild/@electron/rebuildproduce). Electron has its own ABI, which Node does not share. If you are coming from Electron, rebuild against Node:npm rebuild # or, against a specific Node: npm_config_runtime=node npm_config_target=$(node -p process.versions.node) npm rebuildCode that assumes Electron APIs (
electron,app,process.parentPort,utilityProcess). Owear shimsprocess.parentPortfor workers, butrequire('electron')does not exist. Port those parts to@owear/core.
Example: an N-API addon from the main process
import { app } from '@owear/core'
import Database from 'better-sqlite3' // N-API prebuild
app.whenReady().then(() => {
const db = new Database('cache.db')
db.exec('create table if not exists kv (k text primary key, v text)')
})
better-sqlite3 installs its Node prebuild and loads directly; the kernel is not
involved.
Packaging notes
The Node runtime is resolved at the destination — you never ship a Node per
app. The .node files your app installs live in node_modules/ and travel with
the app. To distribute:
- Build/install against a Node compatible with the one the user will resolve (N-API makes this a non-issue).
- Do not bundle Electron binaries.
- If the addon ships per-platform prebuilds, include the target one
(
linux-x64,win32-x64).
For a single-binary app, the CLI bundles your main process with its dependencies
so node_modules is not required at runtime.
Workers and addons
const w = app.forkWorker('heavy-worker.js')
w.postMessage({ op: 'init' })
The worker uses the same Node and can require('sharp') or load its own .node.
Next steps
- Main process —
ensureNodeRuntimeand workers. - Native modules — C++ modules inside the kernel (a different mechanism from N-API addons).