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

atomics-sync

v1.0.3

Published

JavaScript multithreading synchronization library

Downloads

8

Readme

Atomics Sync

Atomics Sync is lightweight library providing thread-safe synchronization primitives for JavaScript environments with shared memory support (Web Workers, Node.js worker_threads). Implements essential concurrency control mechanisms using SharedArrayBuffer and Atomics API.

Features

  • Mutex - Mutual exclusion lock for critical sections
  • SpinLock - Low-level busy-wait lock for very short operations
  • Semaphore - Counting semaphore for resource management
  • Condition - Condition variables for thread signaling
  • Barrier - Synchronization point for multiple threads
  • Once - One-time initialization primitive

Important: For browsers, your server must send these headers:

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

Installation

npm install atomics-sync

Why This Library?

Modern JavaScript applications increasingly use:

  • Web Workers for parallel processing
  • SharedArrayBuffer for shared memory
  • CPU-intensive tasks (WASM, WebGL, etc.)

These primitives help coordinate work between threads while preventing:

  • Race conditions
  • Data corruption
  • Deadlocks

Usage Examples

Important: There is no reliable way for a thread to know its own ID automatically in JavaScript environments. The parent/main thread must explicitly assign and pass a unique thread ID to each worker thread it creates.

Mutex

Init mutex to work safely with shared data:

const shared = new Int32Array(
  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT)
);
const mutex = Mutex.init();

Pass mutex and shared to threads. Remember about threadId:

const worker = new Worker("./worker.js", {
  workerData: { threadId, shared, mutex }
});

Within thread use lock/unlock methods to wrap critical section:

try {
  Mutex.lock(mutex, threadId);
  // work with shared data here
} finally {
  Mutex.unlock(mutex, threadId);
}

See full example.

Semaphore

Here's a practical example demonstrating how to use a semaphore to make one thread wait for another thread to complete certain actions:

Init semaphore:

const sem = Semaphore.init(0);

One thread creates another thread and must wait some initialization actions within it:

new Worker("./worker.js", { workerData: { sem } });
Semaphore.wait(sem);
// continue execution
// ...

Created thread performs necessary operations and notify parent thread:

// ...
initSomeImportantThings();
Semaphore.post(sem);

See full example.

Condition

Using a condition variable, we can make one thread wait for a change in a shared variable (protected by a mutex) before proceeding with its operation.

Init condition variable and mutex, allocate shared variable:

const cond = Condition.init();
const mtx = Mutex.init();
const shared = new Int32Array(
  new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT)
);
shared[0] = -1;

One thread produces value:

Mutex.lock(mtx, threadId);
shared[0] = Math.floor(Math.random() * 10);
Condition.signal(cond);
Mutex.unlock(mtx, threadId);

Another thread consumes the value and makes some work with it:

Mutex.lock(mtx, threadId);

while (shared[0] < 0) {
  Condition.wait(cond, mtx, threadId);
}

shared[0] *= 10;
Mutex.unlock(mtx, threadId);

See full example.

SpinLock

A spinlock provides an interface nearly identical to a mutex (lock()/unlock()), but is optimized for very short wait times where spinning (busy-waiting) is more efficient than thread suspension.

Barrier

A barrier synchronizes multiple threads at a specific execution point.

In this example, we launch 10 threads that execute at variable speeds and create a barrier with a count of 5.

// main.js

const barrier = Barrier.init(5);

for (let i = 0; i < 10; i++) {
  const threadId = i + 1;
  const worker = new Worker("./worker.js", {
    workerData: { threadId, barrier }
  });
}

// worker.js

setTimeout(() => {
  // ...
  Barrier.wait(barrier, threadId);
  // ...
}, threadId * 100);

The first 5 threads to reach the barrier will block and wait.

Once the 5th thread arrives, the barrier releases all waiting threads.

The remaining 5 threads then proceed through the barrier in the same way.

See full example.

Once

A Once primitive ensures one-time initialization in concurrent environments.

Init once value:

const once = Once.init();

Pass it into some threads:

const worker = new Worker("./worker.js", {
  workerData: { once }
});

Within thread:

Once.execute(once, () => {
  // some logic that should be executed only once
});

See full example.

Documentation

For complete API reference, see API documentation.