async-mutex
Mutex and semaphore primitives for synchronizing async workflows in JavaScript and TypeScript.
Repository Health
Technical Analysis
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
Directus
CMS · Low Code Platforms
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.
Firecrawl
AI Development · Developer Tools
Turn any website into clean, LLM-ready data with a single API call — no proxy headaches, no scraping complexity.
Flowise
AI Development · Automation · Developer Tools
Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.
Grist
Databases · No Code Platforms
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.
Hexabot
AI Development · Automation
Build and run agentic workflows across channels with YAML, tools, and RAG
Joplin
Note Taking
The privacy-first, open-source note-taking app with end-to-end encrypted sync, AI assistance, and a powerful plugin ecosystem across every platform.
Karakeep
Bookmarks Archiving
Self-hosted bookmark manager that captures links, notes, images, and PDFs with AI tagging, full-text search, and automatic archiving.
Mastodon
Social Media
Run your own federated social network on the open ActivityPub standard with no ads, no algorithms, and no corporate control over your community.
Mastra Code
AI Code Assistants
"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.