Registry / observability / cls-hooked

cls-hooked

JSON →
library4.2.2jsnpmunverified

cls-hooked is a Node.js library that provides Continuation-Local Storage (CLS), a mechanism akin to thread-local storage but adapted for Node.js's asynchronous, callback-based execution model. It enables developers to maintain and implicitly pass contextual data across asynchronous operations without explicit parameter passing. The current stable version, 4.2.2, primarily targets Node.js versions `^4.7 || >=6.9 || >=7.3 || >=8.2.1`. Its key differentiator lies in its implementation, which leverages Node.js's internal, lower-level APIs: `AsyncWrap` for Node.js versions prior to v8 (an unofficial API), and the `async_hooks` API for Node.js v8.2.1 and newer (which is considered experimental). This approach distinguishes it from its predecessor, `node-continuation-local-storage`, which relied on the now-deprecated `async-listener`. The project's release cadence is largely influenced by the evolution and stability of these underlying Node.js APIs, aiming to provide a robust CLS implementation despite the experimental nature of its core dependencies.

npm install cls-hooked
INSTALL
IMPORT
SIG · CLS-HOOKED
C
cls-hooked
observabilityjavascriptv4.2.2
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 cls = require('cls-hooked'); const myNamespace = cls.createNamespace('my-app');
import { createNamespace } from 'cls-hooked';
Primary usage is CommonJS `require` due to Node.js engine targets (v4+). Direct ESM `import` may require bundler or Node.js loader configuration.
getNamespace
const cls = require('cls-hooked'); const myNamespace = cls.getNamespace('my-app');
import { getNamespace } from 'cls-hooked';
Used to retrieve an already created namespace. Ensure the namespace has been created via `createNamespace` first.
Namespace.run
const session = cls.createNamespace('my-session'); session.run(() => { /* contextual code here */ });
The `run` method establishes the continuation-local storage context for the duration of the provided function. All `set`/`get` operations within this callback's async flow will use this context.

This quickstart demonstrates how to create and manage continuation-local storage contexts using `cls-hooked`'s `createNamespace`, `run`, `set`, and `get` methods, including persistence across asynchronous operations and nested contexts.

const cls = require('cls-hooked'); const session = cls.createNamespace('my-app-session'); console.log('--- Starting CLS Example ---'); function performAsyncTask(callback) { setTimeout(() => { // Simulate some async operation that takes time console.log(`[Async Task] Inside async operation. Context user: ${session.get('user') || 'N/A'}`); callback(); }, 50); } session.run(() => { const requestId = 'req-123'; session.set('requestId', requestId); session.set('user', 'Alice'); console.log(`[Main Thread] Initial context set. Request ID: ${session.get('requestId')}, User: ${session.get('user')}`); performAsyncTask(() => { // Even after an async operation, the context should persist console.log(`[Callback 1] After async task. Request ID: ${session.get('requestId')}, User: ${session.get('user')}`); // Call another function that accesses the context anotherFunction(); // Now, run another context nested within session.run(() => { session.set('user', 'Bob'); // This should be specific to the nested run console.log(`[Nested Context] Inside nested run. Request ID: ${session.get('requestId')}, User: ${session.get('user')}`); performAsyncTask(() => { console.log(`[Nested Callback] After nested async task. Request ID: ${session.get('requestId')}, User: ${session.get('user')}`); }); }); console.log(`[Callback 1 Cont.] After nested context block. User: ${session.get('user')} (should be Alice again)`); }); }); function anotherFunction() { console.log(`[Another Function] Accessing context. Request ID: ${session.get('requestId')}, User: ${session.get('user')}`); } // Outside any 'run' block, the context should not be available setTimeout(() => { console.log(`[Outside Context] After all operations. Request ID: ${session.get('requestId') || 'N/A'}, User: ${session.get('user') || 'N/A'}`); }, 150);
Debug
Known issues
gotchaWhen running `cls-hooked` on Node.js versions prior to v8, the library relies on Node.js's internal `AsyncWrap` API, which is unofficial, undocumented, and not guaranteed to be stable or supported across Node.js minor versions. Use in production environments should consider this inherent risk.
fix
Consider upgrading to Node.js v8.2.1 or newer to utilize the `async_hooks` API. Be aware of the `async_hooks` API's experimental status.
affects: <8.0.0
gotchaFor Node.js versions v8.2.1 and above, `cls-hooked` utilizes the `async_hooks` API, which is labeled as `Experimental` by Node.js. This implies that the API may undergo breaking changes in future Node.js releases without a major version increment, potentially requiring updates to `cls-hooked` itself.
fix
Regularly update `cls-hooked` to its latest version to ensure compatibility with newer Node.js releases, especially those introducing changes to the `async_hooks` API.
affects: >=8.2.1
breakingThe underlying `async_hooks` API in Node.js has undergone breaking changes, for example, noted around Node.js v8.2.0, which necessitated specific updates within `cls-hooked` (e.g., v5.alpha.1 notes this). These changes in Node.js itself can break `cls-hooked` functionality if not using a compatible version.
fix
Ensure your `cls-hooked` version is compatible with your Node.js version. Refer to `cls-hooked` release notes and `engines` field in `package.json` for specific compatibility information.
affects: >=8.0.0
gotchaPrior to version 4.2.1, `cls-hooked` had known issues with memory leaks due to improper handling of asynchronous resources. These leaks could accumulate over time in long-running applications.
fix
Upgrade to `cls-hooked` version 4.2.1 or newer to benefit from memory leak reductions and improvements.
affects: <4.2.1
Errors
Common errors & fixes
Error: A namespace called 'my-app-session' already exists. Use getNamespace(name) to retrieve a namespace.
Attempting to create a new continuation-local storage namespace using `createNamespace(name)` with a name that is already in use.
fix
If a namespace with the desired name might already exist, retrieve it using `const myNamespace = cls.getNamespace('my-app-session');` instead of `createNamespace`.
TypeError: Cannot read properties of undefined (reading 'set')
This error occurs when attempting to call `namespace.set()` or `namespace.get()` outside of an active CLS context, meaning the code is not running within a `namespace.run()` block or a function bound by `namespace.bind()`.
fix
Ensure that any code that needs to access or modify the CLS context is executed within a `namespace.run(function() { ... })` block, or by passing functions through `namespace.bind(func)` to propagate the context.
Error: The 'this' context of 'AsyncResource' is not an instance of AsyncResource
This is a low-level error originating from Node.js's internal `async_hooks` or `AsyncWrap` API. It typically indicates an issue with how `cls-hooked` is interacting with the underlying asynchronous resource tracking, potentially due to an unsupported Node.js version, specific asynchronous patterns, or an internal bug in `cls-hooked`.
fix
First, verify that your Node.js version is explicitly supported by `cls-hooked`'s `engines` field. Second, ensure you are using the latest stable version of `cls-hooked` to benefit from any bug fixes related to `async_hooks` compatibility. If the problem persists, review complex or non-standard asynchronous flows in your application.
Upgrade
Version history
4.2.2latest on npm
Audit
Dependencies
async-hook-jlrequiredCore dependency for `AsyncWrap` implementation, a fork of `async-hook` to address engine semver issues and provide Babel support.
Agent activity
31 hits · last 30 days
node
27
OpenAI (training)
1
Resources
cls-hooked — npm install cls-hooked · libregistry