npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@3leaps/sysprims

v0.2.4

Published

GPL-free cross-platform process utilities (TypeScript bindings via Node-API native addon)

Readme

sysprims (TypeScript bindings)

TypeScript bindings for sysprims using a Node-API (N-API) native addon.

Platform Support

Supported prebuild targets:

  • Linux x64 and arm64: glibc and musl
  • macOS: arm64
  • Windows: x64 and arm64 (MSVC)

Runtime support:

  • Node.js >= 18
  • Bun >= 1.3, verified against the Node-API binding surface

Installation

npm install @3leaps/[email protected]

The package and its platform-specific native packages are published from the verified v0.2.4 repository tag.

For local development from this repository:

npm install
npm run build
npm run build:test

Native prebuild artifacts are produced by the repository release workflows.

Repository Public API Drift Checks

The checked-in public API reference is generated from emitted declarations and checked against the reviewed capability contract, the committed C header, and the N-API inventory.

These are repository-development commands. The generator scripts are not part of the published runtime package.

npm run api:generate      # update docs/public-api.md
npm run api:check         # generate in a temporary directory and compare
npm run api:check:native  # also require and inspect a built local addon

Run npm run build:native before api:check:native. The regular check inspects the addon automatically when one is available and otherwise validates the static, source-independent N-API contract used by pull requests without native artifacts.

To inventory a freshly generated header instead of the committed default, set SYSPRIMS_C_HEADER=/path/to/sysprims.h or pass --c-header /path/to/sysprims.h directly to node scripts/public-api.js check.

make typescript-api-check remains a standalone repository target rather than part of make check: the general Rust gate does not install Node dependencies. Pull-request CI installs dev tooling with npm install --omit=optional before the drift check because release-prep branches reference same-version platform packages before those packages exist in the npm registry. CI also generates a fresh C header for comparison with current Rust exports.

API

Managed contained spawn

spawnContained(argv, options?) returns a ContainedProcess with async identity(), poll(), wait(), terminate(), and close() methods, plus Symbol.asyncDispose. wait({ timeoutMs: 0 }) (or an omitted timeout) is unbounded. An AbortSignal cancels the JavaScript wait, not the native process or its cleanup; the native wait task can continue until its wait ends.

import { spawnContained } from "@3leaps/sysprims";

const handle = await spawnContained(["sleep", "30"], {
  executionTimeoutMs: 5000,
  graceTimeoutMs: 100,
  killTimeoutMs: 500,
});
try {
  const snapshot = await handle.wait({ timeoutMs: 6000 });
  console.log(snapshot.leader_status);
} finally {
  await handle.close(); // A rejected close leaves the handle retryable.
}

Unix success reports guaranteed race-free acquisition and retained group-signaling eligibility with cooperative_group boundary strength. This is a cooperative process group; descendants that leave it are outside the boundary, so guaranteed does not mean OS-enforced non-escape. Windows rejects managed spawn before argv runs. The handle owns native lifecycle authority; its PID fields are diagnostic only.

The execution deadline runs natively without polling. A bounded wait returns an active/running snapshot on timeout, including while another caller cleans up; it does not terminate the process. A wait that itself owns cleanup may take the configured grace/kill window to finish. A fast child first observed after its deadline remains completed. leader_status == timed_out records execution deadline enforcement; the separate timed_out field records cleanup reap timeout.

Successful close is idempotent. A failed close preserves the handle for retry. Finalizers are a leak backstop; close explicitly for deterministic disposal.

Process Inspection

  • procGet(pid, options?)
  • processList(filter?, options?)
  • ancestors(pid, options?)
  • descendants(pid, options?)
  • listFds(pid, filter?)
  • listeningPorts(filter?)
  • waitPID(pid, timeoutMs)

descendants(pid, options?) collects environment and thread details only when includeEnv or includeThreads is explicitly enabled. These options are off by default. Environment values may contain secrets, platform permissions can limit the available detail, and enriching an entire process tree can increase result size and latency.

Guard And Tree Operations

  • guardStep(config)
  • killDescendants(pid, signal?, options?)
  • terminateTree(pid, config?)

Signal Operations

  • signalSend(pid, signal)
  • signalSendGroup(pgid, signal)
  • terminate(pid)
  • forceKill(pid)
  • killMany(pids, signal)
  • terminateMany(pids)
  • forceKillMany(pids)

Spawn Operations

  • spawnInGroup(config)
  • runSetsid(config)
  • runNohup(config)

Self Introspection

  • selfPGID()
  • selfSID()

Session Spawn Notes

runSetsid and runNohup take argv: string[]; argv[0] is the executable. They do not accept a shell command string.

runSetsid({ wait: false }) returns a spawned child PID with sid and pgid derived structurally from that PID. runNohup does not create a new session: it returns the caller session/process-group context inherited by the child. Supervise a runNohup child by pid; do not process-group-signal the returned pgid.

Detached children inherit the caller environment, with env entries merged as overrides. They can outlive the caller, so scrub secrets from the caller environment before spawning when needed. runNohup opens an explicit output_file with append/create semantics and rejects a final symlink. wait: true blocks the calling thread.

Safety

These bindings call into a process-control library. Validate PIDs from external input and avoid process-group signalling unless the target group is explicitly owned and understood.