{"id":13438,"library":"libnpmhook","title":"npm Registry Hooks API","description":"libnpmhook provides a programmatic API for managing server-side hooks on the npm registry. It enables developers to add, remove, list, and update these hooks, which trigger notifications for various package-related events (e.g., new versions published, packages removed). As of April 2026, the current stable version is 11.12.1 and it is an integral part of the larger npm/cli monorepo, ensuring a consistent and official interface with the npm registry. Releases are frequent, typically aligning with npm CLI updates, providing continuous bug fixes and feature enhancements. Key differentiators include its official backing by npm Inc., direct integration with npm-registry-fetch for consistent network behavior, and support for authentication mechanisms like tokens and OTP for secure operations. The library is built on Node.js and requires specific Node.js versions.","status":"active","version":"11.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/npm/cli","tags":["javascript","npm","hooks","registry","npm api"],"install":[{"cmd":"npm install libnpmhook","lang":"bash","label":"npm"},{"cmd":"yarn add libnpmhook","lang":"bash","label":"yarn"},{"cmd":"pnpm add libnpmhook","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Used internally for all registry interactions; all options are passed through directly to this library.","package":"npm-registry-fetch","optional":false}],"imports":[{"note":"The library exports a single default object containing all API methods.","wrong":"import { hooks } from 'libnpmhook';","symbol":"hooks","correct":"import hooks from 'libnpmhook';"},{"note":"CommonJS usage also accesses the default export object, not named exports directly from the module root.","wrong":"const { add, ls } = require('libnpmhook');","symbol":"hooks (CommonJS)","correct":"const hooks = require('libnpmhook');"},{"note":"Access methods like `add`, `rm`, `ls`, `update` as properties of the `hooks` object.","wrong":"import { add } from 'libnpmhook'; add(...);","symbol":"add","correct":"import hooks from 'libnpmhook'; hooks.add(...);"}],"quickstart":{"code":"import hooks from 'libnpmhook';\n\nasync function manageNpmHooks() {\n  // Generate a unique package name for example purposes\n  const packageName = 'example-package-' + Math.random().toString(36).substring(7);\n  const endpointUrl = 'https://example.com/webhook-receiver'; // Replace with your actual endpoint\n  const secret = 'superSecretKey123'; // Replace with a strong, unique secret\n  const authToken = process.env.NPM_TOKEN ?? ''; // Set NPM_TOKEN env var with your npm automation token\n  const otpCode = process.env.NPM_OTP ?? ''; // Optional: set NPM_OTP env var if 2FA is enabled\n\n  if (!authToken) {\n    console.error(\"Error: NPM_TOKEN environment variable is not set. Please provide an npm automation token.\");\n    return;\n  }\n\n  try {\n    console.log(`Attempting to add a hook for package: ${packageName}`);\n    const addedHook = await hooks.add(packageName, endpointUrl, secret, {\n      token: authToken,\n      otp: otpCode // OTP might be required if 2FA is enabled on your account\n    });\n    console.log('Successfully added hook:', addedHook);\n\n    console.log(`\nListing all hooks for package: ${packageName}`);\n    const packageHooks = await hooks.ls(packageName, { token: authToken });\n    console.log(`Hooks found for ${packageName}:`, packageHooks);\n\n    // Clean up: Remove the created hook\n    if (addedHook && addedHook.id) {\n      console.log(`\nRemoving hook with ID: ${addedHook.id}`);\n      await hooks.rm(addedHook.id, { token: authToken, otp: otpCode });\n      console.log('Hook removed successfully.');\n    }\n\n  } catch (error) {\n    console.error('Error managing npm hooks:', error.message);\n    if (error.code === 'EOTP') {\n      console.error('A One-Time Password (OTP) is required for this operation. Please set NPM_OTP environment variable.');\n    } else if (error.code === 'E401' || error.code === 'E403') {\n      console.error('Authentication failed. Check your NPM_TOKEN and permissions.');\n    }\n  }\n}\n\nmanageNpmHooks();","lang":"javascript","description":"Demonstrates how to add, list, and remove an npm registry hook for a package, including necessary authentication and OTP handling."},"warnings":[{"fix":"Upgrade your Node.js runtime to version 18.17.0 or newer, or 20.5.0 or newer.","message":"libnpmhook requires Node.js versions ^18.17.0 || >=20.5.0. Older Node.js environments are not supported and will result in errors.","severity":"breaking","affected_versions":"<18.17.0, <20.5.0"},{"fix":"Ensure `opts.token` is provided with an npm automation token for all registry operations. For publishing-related hooks, this token typically requires write permissions.","message":"All operations interacting with the npm registry require authentication. Failing to provide a valid `opts.token` will result in E401 Unauthorized or E403 Forbidden errors.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Catch errors and check for `err.code === 'EOTP'`. If encountered, prompt the user for their OTP and retry the request including `{otp: <2fa token>}` in the options.","message":"Certain operations, especially those involving sensitive changes (like adding/removing hooks for a package or scope owned by a 2FA-enabled account), may require a One-Time Password (OTP). If an operation fails with `err.code === 'EOTP'`, you must retry the request with `opts.otp` set to the current OTP.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use `await` with `async` functions or explicitly handle returned Promises with `.then()` and `.catch()` blocks.","message":"All API methods return Promises. Forgetting to `await` or handle the promise (`.then()/.catch()`) will lead to unhandled promise rejections and unexpected behavior.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Provide a valid npm automation token via `opts.token` for all registry operations. Check your token's permissions and expiry.","cause":"Missing or invalid authentication token provided in options.","error":"Error: E401 Unauthorized"},{"fix":"Retry the operation, including `{otp: '<your-6-digit-otp>'}` in the options object.","cause":"The requested operation requires a One-Time Password because the account has two-factor authentication enabled.","error":"Error: EOTP"},{"fix":"Ensure you are importing the default export: `import hooks from 'libnpmhook';` or `const hooks = require('libnpmhook');` and then call `hooks.add(...)`.","cause":"Attempting to destructure methods from the module directly instead of accessing them via the default exported 'hooks' object.","error":"TypeError: hooks.add is not a function"},{"fix":"Run `npm install libnpmhook` to add the package to your project dependencies.","cause":"The package is not installed or the import/require path is incorrect.","error":"Error: Cannot find module 'libnpmhook'"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null}