{"id":10863,"library":"exponential-backoff","title":"Exponential Backoff Retry Utility","description":"The `exponential-backoff` package provides a robust utility for retrying asynchronous (Promise-returning) functions with an exponential delay between attempts. Currently stable at version 3.1.3, the library maintains an active development status with regular chore and security updates, although it does not adhere to a strict release cadence. Its key differentiators include extensive configurability through the `BackOffOptions` object, allowing control over aspects like initial delay, maximum delay, number of attempts, jitter application (`full` or `none`), and a custom `retry` function for conditional reattempts. The package ships with TypeScript types, enhancing developer experience in TypeScript projects. It is designed to be a flexible solution for handling transient errors in network requests, database operations, or other unreliable processes.","status":"active","version":"3.1.3","language":"javascript","source_language":"en","source_url":"https://github.com/coveooss/exponential-backoff","tags":["javascript","exponential","backoff","retry","typescript"],"install":[{"cmd":"npm install exponential-backoff","lang":"bash","label":"npm"},{"cmd":"yarn add exponential-backoff","lang":"bash","label":"yarn"},{"cmd":"pnpm add exponential-backoff","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The library primarily uses ESM exports. While CommonJS `require` might work via transpilation or bundlers, native ESM `import` is the recommended and most reliable approach since v3.","wrong":"const { backOff } = require('exponential-backoff');","symbol":"backOff","correct":"import { backOff } from 'exponential-backoff';"},{"note":"Used for TypeScript type declarations. Import with `type` keyword for tree-shaking and clarity, although a regular named import works at runtime if it were a value.","wrong":"import { BackOffOptions } from 'exponential-backoff';","symbol":"BackOffOptions","correct":"import type { BackOffOptions } from 'exponential-backoff';"},{"note":"Type import for the 'jitter' option, defining possible string literal values 'full' or 'none'.","symbol":"JitterType","correct":"import type { JitterType } from 'exponential-backoff';"}],"quickstart":{"code":"import { backOff } from 'exponential-backoff';\n\ninterface WeatherResponse {\n  temperature: number;\n  unit: string;\n}\n\n// Simulate an unreliable API call\nlet attemptCount = 0;\nfunction getUnreliableWeather(): Promise<WeatherResponse> {\n  attemptCount++;\n  console.log(`Attempting to fetch weather... (Attempt ${attemptCount})`);\n  return new Promise((resolve, reject) => {\n    if (Math.random() > 0.7 || attemptCount >= 3) { // Succeeds on ~30% chance or after 3 attempts\n      resolve({ temperature: 25, unit: 'C' });\n    } else {\n      reject(new Error('Failed to fetch weather data.'));\n    }\n  });\n}\n\nasync function main() {\n  try {\n    console.log('Starting weather fetch with exponential backoff...');\n    const response = await backOff(\n      () => getUnreliableWeather(),\n      {\n        numOfAttempts: 5, // Try up to 5 times\n        startingDelay: 200, // Start with 200ms delay\n        timeMultiple: 2, // Double delay each time\n        maxDelay: 5000, // Max 5 seconds delay\n        jitter: 'full',\n        retry: (e, attemptNumber) => {\n          console.warn(`Retry attempt ${attemptNumber}: ${e.message}`);\n          return true; // Always retry for now\n        }\n      }\n    );\n    console.log('Successfully fetched weather:', response);\n  } catch (e: any) {\n    console.error('Failed to fetch weather after multiple retries:', e.message);\n  } finally {\n    console.log(`Total attempts: ${attemptCount}`);\n  }\n}\n\nmain();","lang":"typescript","description":"Demonstrates how to use `backOff` to retry an unreliable asynchronous function with custom exponential backoff options, including delay, attempts, jitter, and a custom retry condition."},"warnings":[{"fix":"Refer to the package's GitHub repository for the dedicated migration guide (`/doc/migration-guide.md`) to understand specific changes and update your code accordingly.","message":"Major versions (e.g., v2 to v3) often introduce breaking changes to the API, options, or internal behavior. Always consult the official migration guide when upgrading between major versions.","severity":"breaking","affected_versions":">=2.0"},{"fix":"Explicitly define a `numOfAttempts` or implement a custom `retry` function that returns `false` under specific error conditions or after a certain number of attempts to prevent uncontrolled retries.","message":"The default `retry` function always returns `true`. If `numOfAttempts` is set to `Infinity` (which is the default `maxDelay` but `numOfAttempts` defaults to 10), and your `request` function consistently fails, it can lead to an infinite retry loop.","severity":"gotcha","affected_versions":">=1.0"},{"fix":"Ensure `numOfAttempts` is explicitly set to `1` or higher. For no retries, simply call the promise-returning function directly without `backOff`.","message":"The `numOfAttempts` option has a minimum value of `1`. Providing a value less than `1` will result in the option being clamped to `1`, which might lead to unexpected behavior if you intend zero retries.","severity":"gotcha","affected_versions":">=1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are using standard ESM `import { backOff } from 'exponential-backoff';`. If using CommonJS, check your transpilation settings to ensure ESM imports are correctly handled or consider updating your build tools. In some cases, a package might not correctly expose its exports for CommonJS.","cause":"This error typically occurs in environments (like Webpack or Babel) when trying to `require` an ESM-first package or due to incorrect default/named import resolution. It indicates the bundler couldn't find the `backOff` export.","error":"TypeError: (0 , exponential_backoff__WEBPACK_IMPORTED_MODULE_0__.backOff) is not a function"},{"fix":"Configure `numOfAttempts` to a finite, reasonable number. Alternatively, provide a custom `retry` function that checks the error (`e`) or `attemptNumber` and returns `false` to stop retrying when a certain condition is met (e.g., non-transient error, max attempts reached).","cause":"You likely have `numOfAttempts` set to a very high number (or effectively `Infinity` due to an oversight) and are using the default `retry` function, which always returns `true`.","error":"My function keeps retrying indefinitely even after many failures."},{"fix":"Review the `BackOffOptions` interface and the available options in the documentation. Correct any misspelled option names or remove unsupported properties from the options object.","cause":"This TypeScript error indicates you're passing an option to `backOff` that is not part of the `BackOffOptions` interface, likely due to a typo or using a deprecated option name.","error":"Argument of type '(...)' is not assignable to parameter of type 'BackOffOptions'. Object literal may only specify known properties, and '' does not exist in type 'BackOffOptions'."}],"ecosystem":"npm"}