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

pthread.js

v0.2.5

Published

A pthread-inspired JavaScript concurrency library with runtime downscaling for Node.js and browsers.

Readme

pthread.js

pthread.js is a pthread-inspired JavaScript library for Node.js and browsers. It exposes pthread-style names, selects the strongest runtime available, and downscales when shared memory is missing or blocked.

Runtime selection is automatic:

  1. shared-memory: SharedArrayBuffer plus blocking Atomics.
  2. message-worker: Web Workers or Node.js worker_threads without shared memory.
  3. promise: same-event-loop scheduling for restricted runtimes.

Fallback runtimes cannot exactly reproduce native blocking semantics. In those modes, operations that would block in C can return a Promise<number>.

Table of Contents

Install

npm install pthread.js

JavaScript Usage

import Thread from 'pthread.js';

const thread = new Thread();

await thread.pthread_create(async value => {
  return value * 2;
}, 21);

console.log(await thread.pthread_join());

Worker Usage

import Thread from 'pthread.js';

const thread = new Thread();
await thread.pthread_create(new URL('./worker.mjs', import.meta.url), { left: 2, right: 3 });
console.log(await thread.pthread_join());
import { pthread_worker_main } from 'pthread.js/worker';

pthread_worker_main(async arg => {
  return arg.left + arg.right;
});

Web Usage

Use pthread.js directly from jsDelivr with one <script> tag:

<button id="run">Run</button>
<output id="result"></output>

<script type="module">
  import Thread, { detectRuntime } from 'https://cdn.jsdelivr.net/npm/[email protected]/index.js';

  const button = document.querySelector('#run');
  const result = document.querySelector('#result');

  button.addEventListener('click', async () => {
    const thread = new Thread();
    await thread.pthread_create(async name => `hello ${name}`, 'browser');
    result.textContent = await thread.pthread_join();
    console.table(detectRuntime());
  });
</script>

The browser automatically downscales. If SharedArrayBuffer and blocking Atomics are available, pthread.js uses the shared-memory backend. If not, it uses Web Workers. If workers are not available, it uses the promise backend.

To enable the strongest browser backend, serve your app with cross-origin isolation headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

In Express:

app.use((req, res, next) => {
  res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
  res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp');
  next();
});

Check the selected backend at runtime:

import Thread, { detectRuntime } from 'https://cdn.jsdelivr.net/npm/[email protected]/index.js';

console.table(detectRuntime());

const thread = new Thread();
console.log(thread.backend.kind);

C pthread vs pthread.js

Native pthread in C:

#include <pthread.h>
#include <stdio.h>

void *run(void *arg) {
  int *value = arg;
  *value = *value * 2;
  return arg;
}

int main(void) {
  pthread_t thread;
  int value = 21;

  pthread_create(&thread, NULL, run, &value);
  pthread_join(thread, NULL);

  printf("%d\n", value);
  return 0;
}

pthread.js:

import Thread from 'pthread.js';

const thread = new Thread();

await thread.pthread_create(async value => value * 2, 21);
const value = await thread.pthread_join();

console.log(value);

Native pthread synchronizes real OS threads and memory. pthread.js uses JavaScript workers when the platform allows it, and falls back to cooperative promises when it does not. The API shape is familiar, but JavaScript cannot expose every POSIX scheduling, signal, priority, or process-shared behavior exactly.

API Coverage

Implemented or simulated groups:

| Group | Functions | | --- | --- | | Thread lifecycle | pthread_create, pthread_join, pthread_exit, pthread_detach, pthread_self, pthread_equal | | Cancellation | pthread_cancel, pthread_setcancelstate, pthread_setcanceltype, pthread_testcancel, pthread_cleanup_push, pthread_cleanup_pop | | Mutexes | pthread_mutex_init, pthread_mutex_destroy, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_timedlock, pthread_mutex_unlock | | Mutex attributes | pthread_mutexattr_init, pthread_mutexattr_destroy, pthread_mutexattr_gettype, pthread_mutexattr_settype, pthread_mutexattr_getpshared, pthread_mutexattr_setpshared, pthread_mutexattr_getprotocol, pthread_mutexattr_setprotocol, pthread_mutexattr_getprioceiling, pthread_mutexattr_setprioceiling | | Conditions | pthread_cond_init, pthread_cond_destroy, pthread_cond_wait, pthread_cond_timedwait, pthread_cond_signal, pthread_cond_broadcast | | Condition attributes | pthread_condattr_init, pthread_condattr_destroy, pthread_condattr_getpshared, pthread_condattr_setpshared, pthread_condattr_getclock, pthread_condattr_setclock | | Read-write locks | pthread_rwlock_init, pthread_rwlock_destroy, pthread_rwlock_rdlock, pthread_rwlock_tryrdlock, pthread_rwlock_wrlock, pthread_rwlock_trywrlock, pthread_rwlock_timedrdlock, pthread_rwlock_timedwrlock, pthread_rwlock_unlock | | Read-write attributes | pthread_rwlockattr_init, pthread_rwlockattr_destroy, pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared, pthread_rwlockattr_getkind_np, pthread_rwlockattr_setkind_np | | Thread attributes | pthread_attr_init, pthread_attr_destroy, pthread_attr_getdetachstate, pthread_attr_setdetachstate, pthread_attr_getschedpolicy, pthread_attr_setschedpolicy, pthread_attr_getschedparam, pthread_attr_setschedparam, pthread_attr_getinheritsched, pthread_attr_setinheritsched, pthread_attr_getscope, pthread_attr_setscope, pthread_attr_getstacksize, pthread_attr_setstacksize, pthread_attr_getstack, pthread_attr_setstack, pthread_attr_getguardsize, pthread_attr_setguardsize, pthread_attr_getstackaddr, pthread_attr_setstackaddr | | TLS | pthread_key_create, pthread_key_delete, pthread_setspecific, pthread_getspecific | | One-time init | pthread_once | | Barriers | pthread_barrier_init, pthread_barrier_destroy, pthread_barrier_wait, pthread_barrierattr_init, pthread_barrierattr_destroy, pthread_barrierattr_getpshared, pthread_barrierattr_setpshared | | Spin locks | pthread_spin_init, pthread_spin_destroy, pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock | | Semaphores | sem_init, sem_destroy, sem_wait, sem_trywait, sem_timedwait, sem_post, sem_getvalue | | Scheduling and names | pthread_getconcurrency, pthread_setconcurrency, pthread_setschedparam, pthread_getschedparam, pthread_setschedprio, pthread_getcpuclockid, pthread_getname_np, pthread_setname_np | | Signals and platform extensions | pthread_kill, pthread_sigmask, pthread_atfork, pthread_getaffinity_np, pthread_setaffinity_np, pthread_getattr_np, pthread_attr_getaffinity_np, pthread_attr_setaffinity_np, pthread_getattr_default_np, pthread_setattr_default_np, pthread_timedjoin_np, pthread_tryjoin_np, pthread_clockjoin_np, pthread_yield_np, pthread_is_threaded_np |

Functions that cannot be represented in JavaScript return ENOSYS: pthread_mutex_consistent, pthread_mutex_consistent_np, robust mutex attribute helpers, priority ceiling helpers on live mutexes, and POSIX clock-lock variants.

Minimum Runtime Versions

The shared-memory backend also requires cross-origin isolation in browsers: Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp or equivalent.

| Platform | Shared-memory backend | Message-worker backend | Promise backend | | --- | --- | --- | --- | | Chrome desktop | 92+ | 61+ as ESM, older with bundling | 61+ as ESM | | Edge desktop | 92+ | 79+ as ESM | 79+ as ESM | | Firefox desktop | 79+ | 60+ as ESM | 60+ as ESM | | Safari macOS | 15.2+ | 10.1+ as ESM | 10.1+ as ESM | | Chrome Android | 89+ | 61+ as ESM | 61+ as ESM | | Firefox Android | 79+ | 60+ as ESM | 60+ as ESM | | Safari iOS | 15.2+ | 10.3+ as ESM | 10.3+ as ESM | | Node.js | 12.17+ | 12.17+ | 12.17+ | | Deno | 1.0+ | 1.0+ | 1.0+ | | Bun | 1.0+ | 1.0+ | 1.0+ |

References: MDN SharedArrayBuffer, MDN Atomics, Chrome SharedArrayBuffer updates, MDN Web Workers, and Node.js worker_threads.

License

MIT. See LICENSE.md.