{"id":17603,"library":"exp-correlator","title":"exp-correlator: Async Context and Express Correlation ID","description":"exp-correlator is a Node.js library designed to manage and propagate a correlation ID across asynchronous operations and within Express.js applications. It leverages Node.js's `async_hooks` to automatically track a unique identifier through various async calls, eliminating the need to explicitly pass the ID between functions. The current stable version is 1.0.0, and while a specific release cadence isn't stated, active GitHub workflows suggest ongoing maintenance. Its primary differentiator is the use of `async_hooks` for transparent context propagation, integrating seamlessly as an Express middleware or through a standalone async handler, and providing direct examples for integration with logging libraries like Pino and HTTP clients like exp-fetch.","status":"active","version":"1.0.0","language":"javascript","source_language":"en","source_url":"ssh://git@github.com/BonnierNews/exp-correlator","tags":["javascript","express","middleware","correlation-id","correlation"],"install":[{"cmd":"npm install exp-correlator","lang":"bash","label":"npm"},{"cmd":"yarn add exp-correlator","lang":"bash","label":"yarn"},{"cmd":"pnpm add exp-correlator","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"For `exp-correlator` v1.x, the primary export is CommonJS as shown in the documentation examples. While Node.js `>=14.17` supports ESM, direct `import` might require specific `package.json` configuration or a build step for seamless integration.","wrong":"import { middleware } from 'exp-correlator';","symbol":"middleware","correct":"const { middleware } = require('exp-correlator');"},{"note":"Retrieves the correlation ID from the current async context. Returns `undefined` if no correlation ID context has been established by either the `middleware` or `attachCorrelationIdHandler` in the current async chain.","wrong":"import { getId } from 'exp-correlator';","symbol":"getId","correct":"const { getId } = require('exp-correlator');"},{"note":"Used to manually establish an async context with a correlation ID for a given async function. The correlation ID will be available via `getId()` only within the execution chain of the wrapped function.","wrong":"import { attachCorrelationIdHandler } from 'exp-correlator';","symbol":"attachCorrelationIdHandler","correct":"const { attachCorrelationIdHandler } = require('exp-correlator');"}],"quickstart":{"code":"const express = require('express');\nconst { middleware, getId } = require('exp-correlator');\nconst app = express();\nconst port = 3000;\n\nconst logMessage = async (msg) => {\n  const correlationId = getId(); \n  console.log({ timestamp: new Date().toISOString(), correlationId, msg });\n};\n\n// Simulate an external call that needs the correlation ID\nconst callToExternalSystem = async () => {\n  const correlationId = getId(); \n  console.log({ timestamp: new Date().toISOString(), context: 'external-call', correlationId, message: 'Making external request' });\n  // In a real app, you'd add correlationId to headers, e.g., 'correlation-id'\n  await new Promise(resolve => setTimeout(resolve, 100)); // Simulate network delay\n};\n\napp.use(middleware); // Apply the correlation ID middleware to all incoming requests\n\napp.get('/', async (req, res) => {\n  const initialCorrelationId = getId();\n  await logMessage(\"Request received for /\");\n  await callToExternalSystem();\n  await logMessage(\"After external system call\");\n  res.json({ message: 'Hello World!', correlationId: initialCorrelationId });\n});\n\napp.get('/test', async (req, res) => {\n  const initialCorrelationId = getId();\n  await logMessage(\"Request received for /test\");\n  res.json({ message: 'Test endpoint', correlationId: initialCorrelationId });\n});\n\napp.listen(port, () => {\n  console.log(`Server listening on http://localhost:${port}`);\n  console.log('Try: curl -H \"correlation-id: my-custom-id\" http://localhost:3000');\n  console.log('Or: curl http://localhost:3000/test');\n});","lang":"javascript","description":"Demonstrates how to integrate `exp-correlator` as an Express middleware to automatically track and log correlation IDs across request handlers and nested asynchronous operations without explicitly passing the ID."},"warnings":[{"fix":"Upgrade your Node.js runtime to version `14.17` or newer.","message":"Reliance on `async_hooks` for context propagation means `exp-correlator` requires Node.js `v14.17` or higher. Running on older Node.js versions will result in runtime errors.","severity":"gotcha","affected_versions":"<14.17"},{"fix":"Ensure all code paths intended to access a correlation ID are wrapped by `attachCorrelationIdHandler` or are part of an Express request handled by `middleware`. Debug complex async patterns to confirm context is maintained.","message":"If `getId()` returns `undefined`, it indicates that the code is executing outside an `exp-correlator` context initialized by either the `middleware` or `attachCorrelationIdHandler`. This often happens with event emitters or certain callback patterns that inadvertently break the async flow.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Profile your application under anticipated load. For extreme performance-critical paths where correlation IDs are not strictly necessary, consider opting out or using alternative, explicit passing mechanisms if `async_hooks` overhead is problematic.","message":"While powerful for transparent context management, `async_hooks` can introduce a slight performance overhead in extremely high-throughput applications or those with deeply nested and frequently invoked async operations. Monitor CPU and memory usage under load.","severity":"gotcha","affected_versions":">=1.0"}],"env_vars":null,"search_vec":"'1.0.0':63 'across':25 'activ':73 'applic':31 'async':4,36,46,86,102 'asynchron':26 'automat':39 'cadenc':69 'call':47 'client':117 'context':5,90 'correl':3,8,12,23,126,128 'correlation-id':125 'current':59 'design':17 'differenti':81 'direct':106 'elimin':48 'exampl':107 'exp':2,11,120 'exp-correl':1,10 'exp-fetch':119 'explicit':52 'express':7,96,123 'express.js':30 'fetch':121 'function':57 'github':74 'handler':103 'hook':37,87 'http':116 'id':9,24,55,127 'identifi':43 'integr':92,109 'isn':70 'javascript':122 'leverag':33 'librari':16,112 'like':113,118 'log':111 'mainten':78 'manag':19 'middlewar':97,124 'need':50 'node.js':15,34 'ongo':77 'oper':27 'pass':53 'pino':114 'primari':80 'propag':21,91 'provid':105 'releas':68 'seamless':93 'specif':67 'stabl':60 'standalon':101 'state':72 'suggest':76 'track':40 'transpar':89 'uniqu':42 'use':84 'various':45 'version':61 'within':29 'workflow':75","created_at":"2026-04-23T17:47:08.336450+00:00","updated_at":"2026-04-23T17:47:08.336450+00:00","problems":[{"fix":"Ensure `const app = express();` is executed before attempting to apply `exp-correlator`'s middleware.","cause":"The Express `app` instance was not properly initialized or is not available when `app.use(middleware)` is called.","error":"TypeError: Cannot read properties of undefined (reading 'use')"},{"fix":"Verify that the `middleware` is correctly applied to your Express app or that `attachCorrelationIdHandler` wraps the entry point of your async operation. Review complex async patterns to ensure context is not inadvertently broken.","cause":"The async context for the correlation ID was not properly established, or it was lost due to an unhandled async boundary (e.g., certain event emitter callbacks, `setImmediate` without proper async context propagation).","error":"correlationId is consistently 'undefined' in logs or when retrieved by getId()"},{"fix":"Upgrade your Node.js runtime to version `14.17` or newer to ensure compatibility and correct functionality.","cause":"The application is running on an unsupported Node.js version, which lacks necessary `async_hooks` features or stability.","error":"Error: `exp-correlator` requires Node.js version `14.17` or higher."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/BonnierNews/exp-correlator","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/exp-correlator","openapi_spec":null,"status_page":null,"smithery":null,"categories":["observability"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-22","install_tag":null}}