Skip to content

About

A high-performance parallel runtime for JavaScript, Explicit bounded CPU with persistent workers, ownership-aware transport, streaming backpressure, and defined lifecycle semantics.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Repository files navigation

PJS — Parallel JavaScript Runtime

npm prerelease

PJS runs explicitly registered CPU work in persistent Node workers, with bounded admission and explicit memory ownership. Your application keeps its event loop for I/O; PJS provides a separate compute plane. There are no runtime dependencies.

v1.0.0-rc.2 is the current published prerelease, available on npm as @pjavascript/runtime under next. Windows and Fedora/Linux x64 qualification completed; macOS and ARM64 remain unclaimed. Final v1.0.0 has not been released. RC readiness records the release gates and platform boundaries. The immutable v0.15.0 release remains available. API stability distinguishes core candidates, supported ownership helpers, experimental range APIs and diagnostic statistics.

RC2 established the permanent package identity @pjavascript/runtime@1.0.0-rc.2. The runtime implementation and public API are unchanged from RC1. See the RC2 release note.

This branch prepares the RC4 candidate with the same R1A runtime qualified in RC3. RC3 reached a GitHub prerelease, but its npm workflow stopped before publication because the release validator assumed the wrong npm CLI JSON shape. RC4 corrects that release contract; execution leases and the published npm version remain unchanged.

Install

Install the current prerelease from the public npm package:

npm install @pjavascript/runtime@next

Use @next deliberately until stable v1.0.0 exists; RC2 is a prerelease. Qualified versions: Node 22.13+ within 22.x and 24.x. TypeScript tasks must be compiled to JavaScript first. No CommonJS entrypoint is supplied.

Thirty-second example

Create tasks.mjs:

export function square(value) {
  return value * value;
}

Create basic-run.mjs:

import { PjsRuntime, PjsTaskRegistry } from '@pjavascript/runtime';

const registry = new PjsTaskRegistry();
const square = registry.register(
  'square',
  new URL('./tasks.mjs', import.meta.url),
  'square',
);
const runtime = new PjsRuntime({ registry, workers: 1 });

try {
  await runtime.ready();
  console.log(await runtime.run(square, 12)); // 144
} finally {
  await runtime.shutdown();
}

Run node basic-run.mjs. The repository version is executable and package-tested, or use npm run example:basic from the checkout. Squaring a number teaches the contract; it is too small to benefit from workers.

How it works

Node application
  ├─ event loop / asynchronous I/O
  └─ PJS: bounded admission → fixed worker pool → registered module tasks

Register trusted local file exports before creating the runtime. Each worker imports those modules and keeps its own globals. PJS does not serialize closures, eval source strings, infer parallel safety or replace Node's event loop. Task handle types describe your declared schema; they cannot verify the loaded export.

Choose an API

API Use it for Status
run One explicit task, one promise Core candidate
ready / shutdown Startup and resource lifetime Core candidates
partitionRange Lazy numeric partitions, ordered per-partition outputs Experimental
parallelFor Completion-only ranges and deliberate side effects Experimental
parallelMapRange Flat ordered element output from validated array/typed blocks Experimental
streamRange Incremental completion-order results with count/optional byte backpressure Experimental
transfer / sharedReadonly Explicit moved buffers / reusable shared input Specialized but supported
stats Copied state and cumulative diagnostic counters Diagnostic surface

See the core API guide for contracts and options. Streams carry partition metadata so your application can reconstruct logical order; PJS does not promise ordered stream delivery.

Ownership, backpressure and cancellation

Clone is the default: easy separation with copying/transport cost. transferList moves input ArrayBuffers at dispatch and detaches every sender view; failures or cancellation after dispatch cannot restore ownership. sharedReadonly makes one copy into native SharedArrayBuffer backing; readonly is a contract, not freezing. See memory ownership.

maxQueue bounds waiting logical tasks and rejects overflow with PjsQueueFullError. A deeper queue is not more CPU capacity. Streams separately limit result count and optionally reserve exact or maximum visible binary bytes. Upper-bound success refunds slack on arrival; actual credit lasts until yield. Result credits do not bound RSS, worker allocations, inputs or consumer-retained values. See backpressure.

Cancellation/timeout can settle a caller while its worker is still busy. There is no rollback. run timeouts include remaining startup and queue wait; stream timeouts also include consumer delivery. A crash fails affected work and may replace the worker without retrying the task. Omitted physical leases preserve unbounded execution. The experimental R1 development API adds exclusive run({ executionLease }), restartPolicy, and graceful shutdown({ forceAfter }); these are not in the already-published RC4 artifact. Leases initiate asynchronous containment and retain occupancy until valid completion or confirmed exit. Shutdown still drains indefinitely when escalation is omitted. See lifecycle and errors.

When PJS helps — and when it does not

Coarse CPU work can amortize worker overhead; tiny transforms usually cannot. Ordinary async I/O, cheap native calls and workloads already served well by native async APIs should generally stay there. Independent-block processing does not preserve one continuous compression context.

Choose workers as a resource policy. availableParallelism() is a default input, not a universal optimum: physical cores, SMT, native threads, application headroom and memory matter. More workers can improve throughput while hurting timer or filesystem latency. Measure your workload's crossover, transport and surrounding application rather than relying on a universal size threshold. The performance guide uses retained Windows/Fedora v0.13 and v0.14 evidence without general speedup claims.

The Science of PJS

The Science of PJS teaches concurrency, Node execution, and the cost of parallelism from first principles, using the runtime and its retained experiments as a case study. Later topics include scheduling, memory, and backpressure; you do not need PJS to learn from the material.

Examples and reference

  • Basic run: registration, execution, shutdown.
  • Range work: typed map, completion-only shared output, and a synchronous native compute task.
  • Shared input: immutable reusable numeric backing.
  • Binary streaming: exact/maximum declarations, refunds and application-owned reconstruction.
  • Cancellation: caller settlement versus occupancy.
  • Transfer: move and return dedicated backing buffers.

Statistics and glossary · Architecture · Full inventory · 1.0 readiness · Stabilization report

Development and validation

Local package evaluation

From a checkout, build and pack a local artifact:

npm ci
npm run build
npm pack --workspace @pjavascript/runtime --pack-destination /tmp

Then install that artifact in your ESM application:

npm install /tmp/pjavascript-runtime-1.0.0-rc.4.tgz

Replace /tmp with an absolute temporary directory on your system (for example $env:TEMP in PowerShell). Use npm.cmd if your PowerShell policy blocks npm.ps1.

Validation

npm test
npm run test:contracts
npm run test:types
npm run typecheck:compat
npm run lint
npm run format:check
npm run test:docs
npm run test:package

The package gate packs and installs outside the repository, tests workers/errors, compiles and runs a TypeScript consumer, and executes the examples. test:contracts records individual-test totals even when the local --test runner reports file summaries. Historical research lives under docs and benchmarks; production code imports none of the workload harnesses. See toolchain and the benchmark methodology for their separate purposes.

Contributing and community

Start with the contributor guide for setup, validation, and runtime/API change expectations. See support for questions and issue reporting, the Code of Conduct for community expectations, and the security policy for private vulnerability reporting.

Maintainers: see releasing for trusted npm publication.

MIT licensed. RC2 is published as a prerelease; final v1.0.0 has not been released.

About

A high-performance parallel runtime for JavaScript, Explicit bounded CPU with persistent workers, ownership-aware transport, streaming backpressure, and defined lifecycle semantics.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages