Registry / observability / continuation-local-storage

continuation-local-storage

JSON →
library3.2.1jsnpmunverified

This package provides a userland implementation of Continuation-Local Storage (CLS) for Node.js, a mechanism akin to thread-local storage but adapted for Node's asynchronous callback chains. It allows developers to store and retrieve values that are scoped to the lifetime of a sequence of asynchronous function calls, eliminating the need to explicitly pass context objects (like request IDs or user information) through numerous function parameters. Values are managed within named 'namespaces' using `createNamespace()`, `getNamespace()`, and propagating context via `namespace.run()` or `namespace.bind()`. While a valuable concept, this specific `continuation-local-storage` package (version 3.2.1, last published 8 years ago) is considered superseded. Modern Node.js applications should leverage the native `AsyncLocalStorage` API (available since Node.js v13.10.0, backported to v12) for a more robust and performant solution, or `cls-hooked` for older Node.js versions, both of which utilize `async_hooks`.

npm install continuation-local-storage
INSTALL
IMPORT
SIG · CONTINUATION-LOCAL
C
continuation-local-storage
observabilityjavascriptv3.2.1
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
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
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

createNamespace
const createNamespace = require('continuation-local-storage').createNamespace;
import { createNamespace } from 'continuation-local-storage';
This package is CommonJS-first; use `require` syntax. ESM imports would require transpilation.
getNamespace
const getNamespace = require('continuation-local-storage').getNamespace;
import { getNamespace } from 'continuation-local-storage';
Access named exports directly from the `require` call. Attempting ESM imports without a CJS wrapper will fail.
Namespace
const cls = require('continuation-local-storage'); const session = cls.createNamespace('my session');
const { Namespace } = require('continuation-local-storage'); // Namespace is an interface/type, not a directly exported class
The `Namespace` is an interface/concept, not a directly exposed class for instantiation via `require`. You interact with instances returned by `createNamespace`.

This quickstart demonstrates how to establish and retrieve context within asynchronous call chains using namespaces, including nested contexts, for simulated HTTP requests.

const createNamespace = require('continuation-local-storage').createNamespace; const requestContext = createNamespace('requestContext'); function handleRequest(requestId) { requestContext.run(function () { requestContext.set('requestId', requestId); console.log(`[${requestContext.get('requestId')}] Request started.`); // Simulate an asynchronous database call setTimeout(() => { logActivity('Fetching user data...'); // Simulate another async operation within a nested context requestContext.run(function (nestedContext) { // nestedContext is a copy of the parent context logActivity('Processing user data in nested context...'); requestContext.set('operation', 'processUser'); // The original requestId is still available console.log(`[${requestContext.get('requestId')}:${requestContext.get('operation')}] Nested operation active.`); setTimeout(() => { logActivity('Nested operation complete.'); }, 50); }); }, 100); }); function logActivity(message) { const currentRequestId = requestContext.get('requestId') || 'N/A'; const currentOperation = requestContext.get('operation') || 'N/A'; console.log(`[${currentRequestId}:${currentOperation}] ${message}`); } } // Simulate multiple incoming requests handleRequest('req-1'); setTimeout(() => handleRequest('req-2'), 20); setTimeout(() => handleRequest('req-3'), 150); // This will run after req-1's initial context might have exited // Demonstrates that context is isolated and automatically managed across async calls. // The logActivity function correctly picks up the context for the active request chain.
Debug
Known issues
breakingThis userland implementation of Continuation-Local Storage is largely superseded by Node.js's native `AsyncLocalStorage` API (introduced in v13.10.0, backported to v12). `AsyncLocalStorage` offers superior performance, stability, and integration with the Node.js event loop and `async_hooks`. It is strongly recommended to migrate to the native API for new projects and consider it for existing ones.
fix
For Node.js v12.17.0+ or v13.10.0+, use `AsyncLocalStorage` from `node:async_hooks`. For older Node.js versions, consider `cls-hooked` which is an `async_hooks` based polyfill. Example: `const { AsyncLocalStorage } = require('node:async_hooks'); const als = new AsyncLocalStorage(); als.run(() => als.getStore().set('key', 'value'));`
affects: >=3.0.0 (all versions)
gotchaContext can be lost when integrating with certain third-party libraries, especially those that extensively use promises, custom async patterns, or do not properly 'bind' functions to the CLS context. This can lead to subtle and difficult-to-debug issues where context values unexpectedly become `undefined`.
fix
Ensure all asynchronous callback functions (especially those passed to external libraries or promise chains) are explicitly bound to the current namespace using `namespace.bind(fn)` or `namespace.run(fn)` where applicable. If context loss persists, inspect the specific library's async behavior or consider migrating to `AsyncLocalStorage` which has better compatibility due to being a native primitive.
affects: >=3.0.0
gotchaThis module's approach, like other userland CLS implementations, may involve monkey-patching Node.js internals, which can lead to fragility. Updates to Node.js or other dependencies might inadvertently break the context propagation or introduce unexpected behavior, making maintenance challenging.
fix
Regularly test application behavior across Node.js versions and dependency updates. The most robust solution is to migrate to the native `AsyncLocalStorage` API which avoids userland monkey-patching concerns entirely.
affects: >=3.0.0
Errors
Common errors & fixes
TypeError: Cannot read property 'get' of undefined
Attempting to retrieve a value from a Continuation-Local Storage namespace (`namespace.get()`) when no active context has been established by `namespace.run()` or `namespace.bind()` for the current asynchronous chain. This often happens if an async operation 'escapes' the CLS context.
fix
Ensure that all code paths where `namespace.get()` is called are encapsulated within a `namespace.run()` block, or that relevant functions are explicitly `namespace.bind()`-ed. If using promises, special care must be taken to bind promise callbacks or use a promise-aware CLS library (like `cls-hooked`) or `AsyncLocalStorage`.
Continuation-local storage context is lost after async/await call
The `continuation-local-storage` package has known limitations and often fails to correctly propagate context across modern `async/await` patterns or with certain promise implementations.
fix
This package is not fully compatible with modern `async/await` syntax. Migrate to `cls-hooked` for older Node.js versions or, ideally, `AsyncLocalStorage` for Node.js v12.17.0+ / v13.10.0+. These alternatives are designed to work correctly with promises and `async/await`.
WARNING: continuation-local-storage is still present as a peer dependency on npm and causes warnings.
This specific warning was observed with older versions of `request-promise` or similar libraries that had `continuation-local-storage` as a peer dependency, but might not be fully compatible or would cause issues upon installation.
fix
This is often a transient warning related to older dependency trees. If possible, upgrade all related packages to their latest versions. If the warning persists and is caused by this package directly, the best long-term solution is to migrate away from `continuation-local-storage` to `AsyncLocalStorage` or `cls-hooked`.
Upgrade
Version history
3.2.1latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
32 hits · last 30 days
node
28
OpenAI (training)
1
Resources
continuation-local-storage — npm install continuation-local-storage · libregistry