Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
semaphore
✓ const semaphore = require('semaphore');
✗ import semaphore from 'semaphore';
This package is CommonJS-only and does not support ES Modules. The `require()` call returns the factory function directly, which then needs to be invoked with a capacity.
sem
✓ const sem = require('semaphore')(capacity);
✗ const sem = new semaphore(capacity);
The `require('semaphore')` call returns a function that must be immediately invoked with the desired capacity to create a semaphore instance. It is not a class constructor.
sem.take
✓ sem.take(function() { /* ... */ });
✗ sem.take().then(() => { /* ... */ });
The `take` method uses a callback-based API, typical of Node.js 0.8.0 era, and does not return a Promise. Modern semaphore implementations often offer promise-based APIs for `async/await`.
This quickstart demonstrates how to create a semaphore to limit simultaneous database access within a Node.js HTTP server. It shows taking and leaving the semaphore using its callback-based API.
const semaphore = require('semaphore');
const http = require('http');
// Limit concurrent database access to 1 operation at a time
const dbSemaphore = semaphore(1);
const expensive_database_operation = (callback) => {
console.log('Starting expensive DB operation...');
setTimeout(() => {
const error = Math.random() > 0.8 ? new Error('Database error!') : null;
console.log('Finished expensive DB operation.');
callback(error, 'Data from DB');
}, 1000);
};
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
dbSemaphore.take(function() {
console.log('Semaphore taken, requesting DB operation...');
expensive_database_operation(function(err, data) {
dbSemaphore.leave();
if (err) {
console.error('Request failed:', err.message);
return res.end(`Error: ${err.message}`);
}
res.end(`Success: ${data}`);
});
});
});
const PORT = process.env.PORT ?? 3000;
server.listen(PORT, () => {
console.log(`Server listening on http://localhost:${PORT}`);
console.log('Try opening multiple tabs to http://localhost:3000 to see concurrency limits in action.');
});
Debug
Known issues
breakingThe package is CommonJS-only and relies on `require()` syntax. It will not work natively in ES Module (ESM) environments without a CJS wrapper or bundler configuration. Modern Node.js projects increasingly use ESM by default.fixFor ESM projects, consider using modern promise-based semaphore libraries like `async-sema` or `await-semaphore` that natively support `import` syntax and `async/await`. If you must use this package, configure your bundler (e.g., Webpack, Rollup) to handle CommonJS modules or use dynamic import `import('semaphore')`. affects: All versions (1.1.0)
gotchaThe package is extremely old, last published 9 years ago, targeting Node.js >=0.8.0. It lacks active maintenance, which means potential bugs, security vulnerabilities, or performance issues are unlikely to be addressed.fixFor new projects or existing projects using modern Node.js, it is strongly recommended to use a more actively maintained and feature-rich semaphore implementation. Search npm for 'semaphore' to find current alternatives.
affects: All versions (1.1.0)
gotchaThis package does not provide TypeScript type definitions natively. While `@types/semaphore` exists, it's also not actively maintained and may not fully align with modern TypeScript practices.fixInstall `@types/semaphore` if using TypeScript (`npm install --save-dev @types/semaphore`). Be aware that types might be outdated or incomplete. Alternatively, migrate to a modern semaphore library that ships with native TypeScript support.
affects: All versions (1.1.0)
gotchaThe `sem.take()` method is callback-based. If the callback function throws an error, the semaphore's `leave()` method might not be called, leading to a deadlock where the semaphore never releases its hold and subsequent operations are permanently blocked.fixAlways ensure `sem.leave()` is called, even if errors occur within the `sem.take()` callback. Wrap the critical section in a `try...finally` block if possible, or ensure all error paths explicitly call `sem.leave()`.
affects: All versions (1.1.0)
Errors
Common errors & fixes
ReferenceError: require is not defined
Attempting to import the CommonJS-only `semaphore` package in an ES Module context (e.g., a `.mjs` file or a project with `"type": "module"` in `package.json`).
fixIf using ES Modules, consider migrating to a modern, promise-based semaphore library that supports `import` statements. If you must use this package, you might need to use dynamic `import('semaphore')` or configure a bundler to transform CommonJS. Ensure your file is a CommonJS module (e.g., `.js` without `"type": "module"` or explicitly `.cjs`). TypeError: semaphore is not a function
You are trying to use the result of `require('semaphore')` directly as an object or calling methods on it, but it's actually a factory function that needs to be invoked first.
fixYou must invoke the result of `require('semaphore')` with a `capacity` argument to create a semaphore instance. Correct usage: `const sem = require('semaphore')(capacity);`. Audit
Dependencies
No dependency data recorded yet.