Natives Architecture
@oh-my-pi/pi-natives is a three-layer stack:
- TypeScript wrapper/API layer exposes stable JS/TS entrypoints.
- Addon loading/validation layer resolves and validates the
.nodebinary for the current runtime. - Rust N-API module layer implements performance-critical primitives exported to JS.
This document is the foundation for deeper module-level docs.
Implementation files
packages/natives/src/index.tspackages/natives/src/native.tspackages/natives/src/bindings.tspackages/natives/src/embedded-addon.tspackages/natives/scripts/build-native.tspackages/natives/scripts/embed-native.tspackages/natives/package.jsoncrates/pi-natives/src/lib.rs
Layer 1: TypeScript wrapper/API layer
packages/natives/src/index.ts is the public barrel. It groups exports by capability domain and re-exports typed wrappers rather than exposing raw N-API bindings directly.
Current top-level groups:
- Search/text primitives:
grep,glob,text,highlight - Execution/process/terminal primitives:
shell,pty,ps,keys - System/media/conversion primitives:
image,html,clipboard,system-info,work
packages/natives/src/bindings.ts defines the base interface contract:
NativeBindingsstarts with shared members (cancelWork(id: number))- module-specific bindings are added by declaration merging from each module’s
types.ts Cancellablestandardizes timeout and abort-signal options for wrappers that expose cancellation
Guaranteed contract (API-facing): consumers import from @oh-my-pi/pi-natives and use typed wrappers.
Implementation detail (may change): declaration merging and internal wrapper layout (src/<module>/index.ts, src/<module>/types.ts).
Layer 2: Addon loading and validation
packages/natives/src/native.ts owns runtime addon selection, optional extraction, and export validation.
Candidate resolution model
- Platform tag is
"${process.platform}-${process.arch}". - Supported tags are currently:
linux-x64linux-arm64darwin-x64darwin-arm64win32-x64
- x64 can use CPU variants:
modern(AVX2-capable)baseline(fallback)
- Non-x64 uses the default filename (no variant suffix).
Filename strategy:
- Release:
pi_natives.<platform>-<arch>.node - x64 variant release:
pi_natives.<platform>-<arch>-modern.nodeand/or...-baseline.node - Dev:
pi_natives.dev.node(preferred whenPI_DEVis set)
Platform-specific variant detection
For x64, variant selection uses:
- Linux:
/proc/cpuinfo - macOS:
sysctl machdep.cpu.leaf7_features/machdep.cpu.features - Windows: PowerShell check for
System.Runtime.Intrinsics.X86.Avx2
PI_NATIVE_VARIANT can explicitly force modern or baseline.
Binary distribution and extraction model
packages/natives/package.json includes both src and native in published files. The native/ directory stores prebuilt platform artifacts.
For compiled binaries (PI_COMPILED or Bun embedded runtime markers), loader behavior is:
- Check versioned user cache path:
<getNativesDir()>/<packageVersion>/... - Check legacy compiled-binary location:
- Windows:
%LOCALAPPDATA%/pisces(fallback%USERPROFILE%/AppData/Local/pisces) - non-Windows:
~/.local/bin
- Windows:
- Fall back to packaged
native/and executable directory candidates
If an embedded addon manifest is present (embedded-addon.ts generated by scripts/embed-native.ts), native.ts can materialize the matching embedded binary into the versioned cache directory before loading.
Validation and failure modes
After require(candidate), validateNative(...) verifies required exports (for example grep, glob, highlightCode, PtySession, Shell, getSystemInfo, getWorkProfile, invalidateFsScanCache).
Failure paths are explicit:
- Unsupported platform tag: throws with supported platform list
- No loadable candidate: throws with all attempted paths and remediation hints
- Missing exports: throws with exact missing names and rebuild command
- Embedded extraction errors: records directory/write failures and includes them in final load diagnostics
Guaranteed contract (API-facing): addon load either succeeds with a validated binding set or fails fast with actionable error text.
Implementation detail (may change): exact candidate search order and compiled-binary fallback path ordering.
Layer 3: Rust N-API module layer
crates/pi-natives/src/lib.rs is the Rust entry module that declares exported module ownership:
clipboardfdfs_cacheglobglob_utilgrephighlighthtmlimagekeysprofpsptyshellsystem_infotasktext
These modules implement the N-API symbols consumed and validated by native.ts. JS-level names are surfaced through the TS wrappers in packages/natives/src.
Guaranteed contract (API-facing): Rust module exports must match the binding names expected by validateNative and wrapper modules.
Implementation detail (may change): internal Rust module decomposition and helper module boundaries (glob_util, task, etc.).
Ownership boundaries
At architecture level, ownership is split as follows:
- TS wrapper/API ownership (
packages/natives/src)- public API grouping, option typing, and stable JS ergonomics
- cancellation surface (
timeoutMs,AbortSignal) exposed to callers
- Loader ownership (
packages/natives/src/native.ts)- runtime binary selection
- CPU variant selection and override handling
- compiled-binary extraction and candidate probing
- hard validation of required native exports
- Rust ownership (
crates/pi-natives/src)- algorithmic and system-level implementation
- platform-native behavior and performance-sensitive logic
- N-API symbol implementation that TS wrappers consume
Runtime flow (high level)
- Consumer imports from
@oh-my-pi/pi-natives. - Wrapper module calls into singleton
nativebinding. native.tsselects candidate binary for platform/arch/variant.- Optional embedded binary extraction occurs for compiled distributions.
- Addon is loaded and export set is validated.
- Wrapper returns typed results to caller.
Glossary
- Native addon: A
.nodebinary loaded via Node-API (N-API). - Platform tag: Runtime tuple
platform-arch(for exampledarwin-arm64). - Variant: x64 CPU-specific build flavor (
modernAVX2,baselinefallback). - Wrapper: TS function/class that provides typed API over raw native exports.
- Declaration merging: TS technique used by module
types.tsfiles to extendNativeBindings. - Compiled binary mode: Runtime mode where the CLI is bundled and native addons are resolved from extracted/cache paths instead of only package-local paths.
- Embedded addon: Build artifact metadata and file references generated into
embedded-addon.tsso compiled binaries can extract matching.nodepayloads. - Validation gate:
validateNative(...)check that rejects stale/mismatched binaries missing required exports.