{"id":15520,"library":"async-hook-jl","title":"Node.js Async Hook Abstraction","description":"async-hook-jl is a Node.js library that provides a high-level, stable abstraction over Node.js's internal, currently undocumented `AsyncWrap` API. It enables developers to inspect and hook into the lifecycle of \"handle objects\" (internal resources like network connections, timers, etc.) within the Node.js runtime. This includes events like initialization (`init`), pre-execution (`pre`), post-execution (`post`), and destruction (`destroy`) of asynchronous operations. The library aims to address some inconsistencies in the native `AsyncWrap` API, offer a more uniform interface, and crucially, allow multiple hooks to be registered simultaneously. The current stable version is 1.7.6, with recent updates focusing on compatibility and minor fixes rather than new features. Its primary differentiator is making a powerful, low-level internal Node.js API accessible and more robust for userland modules, with the long-term hope that similar functionality will eventually be integrated directly into Node.js core.","status":"active","version":"1.7.6","language":"javascript","source_language":"en","source_url":"git://github.com/jeff-lewis/async-hook-jl","tags":["javascript","async","async hooks","inspect","async wrap"],"install":[{"cmd":"npm install async-hook-jl","lang":"bash","label":"npm"},{"cmd":"yarn add async-hook-jl","lang":"bash","label":"yarn"},{"cmd":"pnpm add async-hook-jl","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"This library is primarily designed for CommonJS (`require`) environments, consistent with its target Node.js versions. Direct ESM `import` is not officially supported and may not work as expected.","wrong":"import asyncHook from 'async-hook-jl';","symbol":"asyncHook","correct":"const asyncHook = require('async-hook-jl');"},{"note":"All API methods like `addHooks` are properties of the default `asyncHook` object, not named exports.","wrong":"import { addHooks } from 'async-hook-jl';","symbol":"addHooks","correct":"asyncHook.addHooks({ init, pre, post, destroy });"},{"note":"The main module export is `asyncHook` (singular). Be careful not to confuse it with a plural form or a global `async_hooks` module from Node.js core when referring to its methods.","wrong":"asyncHooks.enable();","symbol":"enable","correct":"asyncHook.enable();"}],"quickstart":{"code":"const asyncHook = require('async-hook-jl');\n\nfunction init(uid, handle, provider, parentUid, parentHandle) {\n  console.log(`[INIT] UID: ${uid}, Provider: ${asyncHook.providers[provider]}, Parent UID: ${parentUid}`);\n}\nfunction pre(uid, handle) {\n  console.log(`[PRE] UID: ${uid}`);\n}\nfunction post(uid, handle, didThrow) {\n  console.log(`[POST] UID: ${uid}, DidThrow: ${didThrow}`);\n}\nfunction destroy(uid) {\n  console.log(`[DESTROY] UID: ${uid}`);\n}\n\n// Add the defined hooks\nasyncHook.addHooks({ init, pre, post, destroy });\n\n// Enable the hooks globally\nasyncHook.enable();\n\n// Demonstrate an asynchronous operation\nconsole.log('Starting timer...');\nsetTimeout(() => {\n  console.log('Timer finished after 100ms.');\n}, 100);\n\n// Optional: Disable after some time or specific operations\n// setTimeout(() => {\n//   asyncHook.disable();\n//   console.log('Async hooks disabled.');\n// }, 500);\n","lang":"javascript","description":"This quickstart demonstrates how to initialize `async-hook-jl`, register all four types of lifecycle hooks (`init`, `pre`, `post`, `destroy`), enable them, and observe their output during a simple `setTimeout` operation."},"warnings":[{"fix":"Monitor Node.js release notes closely for changes to internal async APIs. Test `async-hook-jl` extensively when upgrading Node.js versions. Consider forking or using a specific, tested version of Node.js for critical applications.","message":"`async-hook-jl` relies on Node.js's internal, undocumented `AsyncWrap` API. Future Node.js major or even minor versions might introduce breaking changes to `AsyncWrap` that could affect this library's functionality without prior notice, potentially requiring updates or causing unexpected runtime errors.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Only disable hooks if you are certain no other part of your application or its dependencies relies on `async-hook-jl` being active. Prefer conditional hook registration or removal over global disabling where possible.","message":"Disabling hooks globally using `asyncHook.disable()` can lead to conflicts or unexpected behavior with other modules that might also be using `async-hook-jl` or directly interacting with `AsyncWrap`. This can break their functionality or lead to difficult-to-debug side effects.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use `asyncHook` (singular) when interacting with the module's exported object and its methods (e.g., `asyncHook.removeHooks(...)`).","message":"The package's README, specifically in the `removeHooks` example, contains a typo. It incorrectly uses `asyncHooks.removeHooks` (plural) instead of `asyncHook.removeHooks` (singular). Copying this code verbatim will result in a `ReferenceError`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use `const asyncHook = require('async-hook-jl');` to ensure correct module loading, especially in older Node.js versions or mixed CJS/ESM projects.","message":"The `async-hook-jl` module is primarily designed for CommonJS (`require`) environments. While Node.js itself supports ESM, directly importing this module using `import ... from 'async-hook-jl'` may not work as intended or could lead to compatibility issues depending on your Node.js version and configuration.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Change `asyncHooks` to `asyncHook`. For example, `asyncHook.removeHooks(...)` instead of `asyncHooks.removeHooks(...)`.","cause":"The module's main export is named `asyncHook` (singular), but the user might have mistakenly used `asyncHooks` (plural) based on a typo in the README's `removeHooks` example.","error":"ReferenceError: asyncHooks is not defined"},{"fix":"Ensure `const asyncHook = require('async-hook-jl');` is used at the top of your file. Verify that `async-hook-jl` is correctly installed in `node_modules` and that no other variable named `asyncHook` is conflicting.","cause":"This typically occurs if `require('async-hook-jl')` failed to correctly load the module, or if `asyncHook` was reassigned or shadowed, or if the module was imported incorrectly in an ESM context.","error":"TypeError: asyncHook.addHooks is not a function"},{"fix":"Ensure you call `asyncHook.enable();` after calling `asyncHook.addHooks(...)` to activate the hook callbacks.","cause":"The `async-hook-jl` hooks are disabled by default and must be explicitly enabled using `asyncHook.enable()` after registration.","error":"Hooks are registered but not firing (no console output from hook functions)."}],"ecosystem":"npm"}