{"id":12678,"library":"wrappy","title":"Wrappy","description":"Wrappy is a tiny, foundational utility for reliably wrapping callback functions in JavaScript. Its primary function is to ensure that a given callback is invoked at most once, which is crucial for preventing unexpected behavior in asynchronous operations where a callback might inadvertently be called multiple times. Currently stable at version 1.0.2, released in 2015, the package maintains an extremely low release cadence due to its minimal scope and high stability, with updates typically addressing only critical edge cases or compatibility. Wrappy is largely an internal dependency for many other npm packages (e.g., `once`, `inflight`) rather than a direct application-level utility, providing a robust and dependency-free solution for basic callback management.","status":"maintenance","version":"1.0.2","language":"javascript","source_language":"en","source_url":"https://github.com/npm/wrappy","tags":["javascript"],"install":[{"cmd":"npm install wrappy","lang":"bash","label":"npm"},{"cmd":"yarn add wrappy","lang":"bash","label":"yarn"},{"cmd":"pnpm add wrappy","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"CommonJS module import, standard for Node.js environments.","symbol":"wrappy","correct":"const wrappy = require('wrappy')"},{"note":"When using in an ES Module (ESM) environment or with bundlers, `wrappy` is treated as a default export from its CommonJS nature. Attempting a named import (`import { wrappy } from 'wrappy'`) will fail as no such named export exists.","wrong":"import { wrappy } from 'wrappy'","symbol":"wrappy","correct":"import wrappy from 'wrappy'"},{"note":"The `wrappy` function itself is the module's export, not a property of an object. Call it directly after importing.","wrong":"const onceWrapper = wrappy.wrappy(callbackFn)","symbol":"Callback Wrapper","correct":"const onceWrapper = wrappy(callbackFn)"}],"quickstart":{"code":"const wrappy = require('wrappy');\n\n// Define a callback function that we want to ensure runs only once\nlet executionCount = 0;\nfunction myCallback(err, data) {\n  if (err) {\n    console.error('Error:', err);\n    return;\n  }\n  executionCount++;\n  console.log(`Callback executed! Data: ${data}. Total executions: ${executionCount}`);\n}\n\n// Wrap the callback using wrappy\nconst wrappedCallback = wrappy(myCallback);\n\n// Simulate an asynchronous operation where the callback might be called multiple times\nconsole.log('--- Starting async operation simulation ---');\n\nsetTimeout(() => {\n  console.log('Attempting to call wrappedCallback (first time)');\n  wrappedCallback(null, 'Initial Data');\n}, 100);\n\nsetTimeout(() => {\n  console.log('Attempting to call wrappedCallback (second time - should be ignored)');\n  wrappedCallback(null, 'More Data'); // This call should be ignored by wrappy\n}, 200);\n\nsetTimeout(() => {\n  console.log('Attempting to call wrappedCallback (third time - should be ignored)');\n  wrappedCallback(null, 'Even More Data'); // This call should also be ignored\n}, 300);\n\n// Example of wrappy being used for error handling that only triggers once\nfunction saveUserData(user, callback) {\n  const done = wrappy(callback);\n  let dbOperationComplete = false;\n  let fileWriteComplete = false;\n\n  // Simulate two async operations that need to complete, but only one `done` call\n  setTimeout(() => {\n    if (Math.random() > 0.9) return done(new Error('DB connection failed'));\n    dbOperationComplete = true;\n    console.log('DB operation finished.');\n    if (fileWriteComplete) done(null, 'User data saved successfully');\n  }, 150);\n\n  setTimeout(() => {\n    if (Math.random() > 0.9) return done(new Error('File write failed'));\n    fileWriteComplete = true;\n    console.log('File write finished.');\n    if (dbOperationComplete) done(null, 'User data saved successfully');\n  }, 250);\n}\n\nsaveUserData({ id: 1, name: 'Alice' }, (err, result) => {\n  if (err) {\n    console.error('Save user data failed:', err.message);\n    return;\n  }\n  console.log('Save user data success:', result);\n});","lang":"javascript","description":"This quickstart demonstrates how to use `wrappy` to ensure a callback function is executed at most once, even if called multiple times. It includes a basic asynchronous simulation and an example showing how `wrappy` can manage multiple asynchronous completion signals into a single callback trigger."},"warnings":[{"fix":"Consider if Promises, async/await, or other modern async patterns are more suitable for your application's needs before directly integrating `wrappy`.","message":"Wrappy is a low-level utility primarily designed for internal use by library authors, especially for managing asynchronous control flow in older CommonJS patterns. For direct application development, modern alternatives like Promises, async/await, or dedicated event emitters often provide more idiomatic and robust solutions for managing asynchronous operations and ensuring single execution.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use `import wrappy from 'wrappy'` for ESM environments. Avoid named imports.","message":"The `wrappy` package is a CommonJS module. When used in an ES Module (ESM) environment (e.g., with `type: \"module\"` in `package.json` or in a browser build process like Webpack/Rollup), it must be imported as a default export (`import wrappy from 'wrappy'`). Attempting a named import (`import { wrappy } from 'wrappy'`) will result in runtime errors as the named export `wrappy` does not exist.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For more advanced asynchronous control, consider libraries like `async`, `lodash.debounce`, `lodash.throttle`, or implement custom logic using Promises.","message":"Wrappy explicitly guarantees a function is called *at most once*. It does not provide features like retry mechanisms, advanced error handling (beyond passing the error), debouncing, throttling, or complex flow control (e.g., parallel execution, sequencing tasks). Developers needing these more elaborate features should explore other specialized libraries or implement them using Promises.","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":"Change the import statement from `import { wrappy } from 'wrappy'` to `import wrappy from 'wrappy'`.","cause":"This error typically occurs in bundled ES Module (ESM) contexts (e.g., Webpack, Rollup) when `wrappy` is incorrectly imported using a named import syntax (`import { wrappy } from 'wrappy'`) instead of a default import.","error":"TypeError: (0 , wrappy__WEBPACK_IMPORTED_MODULE_0__.wrappy) is not a function"},{"fix":"Ensure you are using `const wrappy = require('wrappy');` in CommonJS and calling `wrappy(callback)` directly. Verify that the `wrappy` variable holds the function reference before attempting to call it.","cause":"This can occur if `wrappy` is imported incorrectly in a CommonJS module, or if the imported `wrappy` variable is not the function itself but perhaps an object, or if it's being called as a method on an undefined object. It often signifies a mismatch in how the module's export is consumed.","error":"TypeError: wrappy is not a function"}],"ecosystem":"npm"}