async-mutex

Mutex and semaphore primitives for synchronizing async workflows in JavaScript and TypeScript.

Library
npm
v0.5.0
1,436 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
37 /100 Needs Attention
Development Activity 0
Maintenance 0
Community 48
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
86 /100 Excellent
Architecture 86
Code Quality 88
Innovation 88
Learning Curve 85

async-mutex is a small, dependency-light library that brings classic concurrency primitives — mutexes and semaphores — to JavaScript’s single-threaded, asynchronous execution model. Although JavaScript runs on one thread, interleaved async operations can still produce race conditions when several tasks touch shared state across multiple spins of the event loop. async-mutex solves this by letting you serialize or rate-limit access to a critical section with promise-based locks.

Written in TypeScript with full type definitions, it exposes both a promise style and an async/await style API, plus higher-order decorators like withTimeout and tryAcquire. It works in any environment supporting ES5, ES6 promises, and Array.isArray, ships CommonJS and ES module builds, and has a single tiny runtime dependency (tslib).

What You Get

  • A Mutex class for exclusive access, with runExclusive, manual acquire/release, isLocked, waitForUnlock, and cancel.
  • A Semaphore class supporting weighted acquisition and task priority for controlling parallel access to N resources.
  • withTimeout and tryAcquire decorators that reject when a lock cannot be obtained within a deadline or immediately.
  • First-class TypeScript typings plus CommonJS and ES module builds usable across Node and the browser.

Common Use Cases

  • Serializing multi-step message exchanges with a web worker or socket so overlapping calls do not corrupt shared state.
  • Limiting the number of concurrent HTTP requests or file operations with a weighted semaphore.
  • Guarding writes to an in-memory cache or database connection that is not safe under interleaved async access.

Under The Hood

Architecture

The library is layered around a single core primitive. Semaphore.ts implements the real scheduling logic: a priority-ordered queue of pending acquirers, a separate list of weighted waitForUnlock waiters, and a dispatch loop (_dispatchQueue/_dispatchItem) that hands out idempotent releasers as the counter allows. Mutex.ts is a thin adapter that simply constructs a Semaphore(1) and delegates every method to it, so a mutex is literally a binary semaphore. withTimeout.ts and tryAcquire.ts are decorators that wrap an existing Mutex or Semaphore and race its acquisition against a setTimeout, with tryAcquire being withTimeout(sync, 0). index.ts re-exports the public surface (Mutex, Semaphore, their interfaces, withTimeout, tryAcquire, and the E_CANCELED/E_TIMEOUT/E_ALREADY_LOCKED error sentinels).

Tech Stack

Pure TypeScript (5.4) targeting ES5+, with tslib as the only runtime dependency. The build runs tsc three times to emit CommonJS (lib), ES6 (es6), and MJS outputs, then bundles the MJS entrypoint with Rollup. Tests use Mocha with ts-node, nyc for coverage, and @sinonjs/fake-timers for deterministic timing; linting is ESLint plus Prettier.

Code Quality

Code quality is high. The src tree is small and cohesive (eight files), each class implements an explicit interface (MutexInterface, SemaphoreInterface), and releasers are made idempotent via a called guard to prevent double-release bugs. A dedicated test directory covers the mutex, semaphore, timeout, and tryAcquire behaviors, including a shared semaphoreSuite and fake-timer-driven timing tests. Weight and priority inputs are validated with explicit thrown errors.

API Design The public API is deliberately ergonomic. runExclusive covers the common case in one call by acquiring, running a callback, and releasing in a finally; manual acquire/release is available for advanced control, and both promise-chaining and async/await styles are documented. Cancellation, timeouts, and non-blocking try-acquire are layered as composable decorators rather than constructor flags, and a thorough README plus a separate API.md keep the learning curve low.

Used by 27 apps in this directory

TypeScript
80%
Other

Directus

CMS · Low Code Platforms

38,629

Connect any SQL database and get instant REST and GraphQL APIs, a visual management Studio, and a native MCP server for AI agents — free for most organizations.

View details
93
Repo Health
82
Technical
76
Dependency
Built with
TypeScript 80%
Vue 19%
Updated 1 weeks ago
TypeScript
72%
AGPL 3.0

Firecrawl

AI Development · Developer Tools

194,745

Turn any website into clean, LLM-ready data with a single API call — no proxy headaches, no scraping complexity.

View details
89
Repo Health
83
Technical
65
Dependency
Built with
TypeScript 72%
Python 12%
Updated 1 weeks ago
TypeScript
62%
Other

Flowise

AI Development · Automation · Developer Tools

55,521

Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.

View details
75
Repo Health
77
Technical
63
Dependency
Built with
TypeScript 62%
JavaScript 27%
Updated 2 months ago
TypeScript
83%
Apache 2.0

Grist

Databases · No Code Platforms

11,991

A modern relational spreadsheet that combines Python-powered formulas, drag-and-drop dashboards, and granular access controls in a self-hostable, SQLite-backed data platform.

View details
91
Repo Health
93
Technical
63
Dependency
Built with
TypeScript 83%
Python 11%
Updated 1 weeks ago
TypeScript
98%
Other

Hexabot

AI Development · Automation

1,160

Build and run agentic workflows across channels with YAML, tools, and RAG

View details
76
Repo Health
76
Technical
65
Dependency
Built with
TypeScript 98%
Updated 1 months ago
TypeScript
77%
Other

Joplin

Note Taking

56,853

The privacy-first, open-source note-taking app with end-to-end encrypted sync, AI assistance, and a powerful plugin ecosystem across every platform.

View details
93
Repo Health
87
Technical
60
Dependency
Built with
TypeScript 77%
JavaScript 14%
Updated 1 weeks ago
TypeScript
98%
AGPL 3.0

Karakeep

Bookmarks Archiving

29,926

Self-hosted bookmark manager that captures links, notes, images, and PDFs with AI tagging, full-text search, and automatic archiving.

View details
88
Repo Health
76
Technical
66
Dependency
Built with
TypeScript 98%
Updated 1 weeks ago
Ruby
59%
AGPL 3.0

Mastodon

Social Media

50,441

Run your own federated social network on the open ActivityPub standard with no ads, no algorithms, and no corporate control over your community.

View details
95
Repo Health
81
Technical
70
Dependency
Built with
Ruby 59%
TypeScript 24%
Updated 1 weeks ago
TypeScript
99%
Apache 2.0

Mastra Code

AI Code Assistants

29,041

"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.

View details
90
Repo Health
73
Technical
65
Dependency
Built with
TypeScript 99%
Updated 1 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers