Natives Addon Loader Runtime
This document deep-dives the addon loading/validation layer in @oh-my-pi/pi-natives: how native.ts decides which .node file to load, when embedded payload extraction runs, and how startup failures are reported.
Implementation files
packages/natives/src/native.tspackages/natives/src/embedded-addon.tspackages/natives/src/bindings.tspackages/natives/package.json
Scope and responsibility
Loader/runtime responsibilities are intentionally narrow:
- Build a platform/CPU-aware candidate list for addon filenames and directories.
- Optionally materialize an embedded addon into a versioned per-user cache directory.
- Attempt candidates in deterministic order.
- Reject stale or incompatible addons via
validateNativebefore exposing bindings.
Out of scope here: module-specific grep/text/highlight behavior.
Runtime inputs and derived state
At module initialization (export const native = loadNative();), native.ts computes static context:
- Platform tag:
${process.platform}-${process.arch}(for exampledarwin-arm64). - Package version: from
packages/natives/package.json(versionfield). - Core directories:
nativeDir: package-localpackages/natives/native.execDir: directory containingprocess.execPath.versionedDir:<getNativesDir()>/<packageVersion>.userDataDirfallback:- Windows:
%LOCALAPPDATA%/pisces(or%USERPROFILE%/AppData/Local/pisces). - Non-Windows:
~/.local/bin.
- Windows:
- Compiled-binary mode (
isCompiledBinary): true if any of:PI_COMPILEDenv var is set, orimport.meta.urlcontains Bun-embedded markers ($bunfs,~BUN,%7EBUN).
- Variant override:
PI_NATIVE_VARIANT(modern/baselineonly; invalid values ignored). - Selected variant: explicit override, otherwise runtime AVX2 detection on x64 (
modernif AVX2, elsebaseline).
Platform support and tag resolution
SUPPORTED_PLATFORMS is fixed to:
linux-x64linux-arm64darwin-x64darwin-arm64win32-x64
Behavior detail:
- Unsupported platforms are not rejected up-front.
- Loader still tries all computed candidates first.
- If nothing loads, it throws an explicit unsupported-platform error listing supported tags.
This preserves useful diagnostics for near-miss cases while still failing hard for truly unsupported targets.
Variant selection (modern / baseline / default)
x64 behavior
- If
PI_NATIVE_VARIANTismodernorbaseline, that value wins. - Else detect AVX2 support:
- Linux: scan
/proc/cpuinfoforavx2. - macOS: query
sysctl(machdep.cpu.leaf7_features, fallbackmachdep.cpu.features). - Windows: run PowerShell
[System.Runtime.Intrinsics.X86.Avx2]::IsSupported.
- Linux: scan
- Result:
- AVX2 available ->
modern - AVX2 unavailable/undetectable ->
baseline
- AVX2 available ->
Non-x64 behavior
- No variant is used; loader stays on the default filename (
pi_natives.<platform>-<arch>.node).
Filename construction
Given tag = <platform>-<arch>:
- Non-x64 or no variant:
pi_natives.<tag>.node - x64 +
modern: try in orderpi_natives.<tag>-modern.nodepi_natives.<tag>-baseline.node(intentional fallback)
- x64 +
baseline: onlypi_natives.<tag>-baseline.node
The addonLabel used in final error messages is either <tag> or <tag> (<variant>).
Candidate path construction and fallback ordering
native.ts builds candidate pools before any require(...) call.
Debug/dev candidates (only when PI_DEV is set)
Prepended first:
<nativeDir>/pi_natives.dev.node<execDir>/pi_natives.dev.node
This path is explicit debug intent and always outranks release candidates.
Release candidates
Built from variant-resolved filename list and searched in this order:
Non-compiled runtime:
<nativeDir>/<filename><execDir>/<filename>
Compiled runtime (
PI_COMPILEDor Bun embedded markers):<versionedDir>/<filename><userDataDir>/<filename><nativeDir>/<filename><execDir>/<filename>
dedupedCandidates removes duplicates while preserving first occurrence order.
Final runtime sequence
At load time:
- Optional embedded extraction candidate (if produced) is inserted at the front.
- Remaining deduplicated candidates are tried in order.
- First candidate that both
require(...)s and passesvalidateNative(...)wins.
Embedded addon extraction lifecycle
embedded-addon.ts defines a generated manifest shape:
platformTagversionfiles[]where each entry hasvariant,filename,filePath
Current checked-in default is embeddedAddon: null; compiled artifacts may replace this with real metadata.
Extraction state machine
Extraction (maybeExtractEmbeddedAddon) runs only when all gates pass:
isCompiledBinary === trueembeddedAddon !== nullembeddedAddon.platformTag === platformTagembeddedAddon.version === packageVersion- A variant-appropriate embedded file is found
Variant file selection mirrors runtime variant intent:
- Non-x64: prefer
default, then first available file. - x64 +
modern: prefermodern, fallback tobaseline. - x64 +
baseline: requirebaseline.
Materialization behavior:
- Ensure
<versionedDir>exists (mkdirSync(..., { recursive: true })). - If
<versionedDir>/<selected filename>already exists, reuse it (no rewrite). - Else read embedded source
filePathand write target file. - Return target path for highest-priority load attempt.
On failure, extraction does not crash immediately; it appends an error entry (directory creation or write failure) and loader proceeds to normal candidate probing.
Lifecycle and state transitions
Init
-> Compute platform/version/variant/candidate lists
-> (Compiled + embedded manifest matches?)
yes -> Try extract embedded to versionedDir (record errors, continue)
no -> Skip extraction
-> For each runtime candidate in order:
require(candidate)
-> success: validateNative
-> pass: return bindings (READY)
-> fail: record error, continue
-> failure: record error, continue
-> none loaded:
if unsupported platform tag -> throw Unsupported platform
else -> throw Failed to load (full tried-path diagnostics + hints)validateNative contract checks
validateNative(bindings, source) enforces a function-only contract over NativeBindings at startup.
Mechanics:
- For each required export name, it checks
typeof bindings[name] === "function". - Missing names are aggregated.
- If any are missing, loader throws:
- source addon path,
- missing export list,
- rebuild command hint.
This is a hard compatibility gate against stale binaries, partial builds, and symbol/name drift.
JS API ↔ native export mapping (validation gate)
JS binding name checked in validateNative | Expected native export name |
|---|---|
grep | grep |
glob | glob |
highlightCode | highlightCode |
executeShell | executeShell |
PtySession | PtySession |
Shell | Shell |
visibleWidth | visibleWidth |
getSystemInfo | getSystemInfo |
getWorkProfile | getWorkProfile |
invalidateFsScanCache | invalidateFsScanCache |
Note: bindings.ts declares only the base cancelWork(id) member; module types.ts files declaration-merge additional symbols that validateNative enforces.
Failure behavior and diagnostics
Unsupported platform
If all candidates fail and platformTag is not in SUPPORTED_PLATFORMS, loader throws:
Unsupported platform: <tag>- Full supported-platform list
- Explicit issue-reporting guidance
Stale binary / mismatch symptoms
Typical stale mismatch signal:
Native addon missing exports (<candidate>). Missing: ...
Common causes:
- Old
.nodebinary from previous package version/API shape. - Wrong variant artifact selected (for x64).
- New Rust export not present in loaded artifact.
Loader behavior:
- Records per-candidate missing-export failures.
- Continues probing remaining candidates.
- If no candidate validates, final error includes every attempted path with each failure message.
Compiled-binary startup failures
In compiled mode final diagnostics include:
- expected versioned cache target paths (
<versionedDir>/<filename>), - remediation to delete stale
<versionedDir>and rerun, - direct release download
curlcommands for each expected filename.
Non-compiled startup failures
In normal package/runtime mode final diagnostics include:
- reinstall hint (
bun install @oh-my-pi/pi-natives), - local rebuild command (
bun --cwd=packages/natives run build:native), - optional x64 variant build hint (
TARGET_VARIANT=baseline|modern ...).
Dev/debug versus release behavior
When PI_DEV is set:
pi_natives.dev.nodecandidates are prepended ahead of all release candidates.- Loader emits per-candidate console diagnostics (
Loaded native addon...and load errors).
Without PI_DEV:
- Only release candidate chain is used.
- No dev console diagnostics are emitted.
Operationally, this means debug sessions can validate an ad-hoc dev addon first, while production/release runs remain on deterministic release artifact probing.