npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fetch-retrier

v0.2.3

Published

A lightweight wrapper around `fetch` that adds **retries**, **timeout**, and **full jitter** backoff. Useful for calling HTTP APIs that may be rate-limited (429) or temporarily unavailable (5xx).

Downloads

934

Readme

Fetch Retrier

A lightweight wrapper around fetch that adds retries, timeout, and full jitter backoff. Useful for calling HTTP APIs that may be rate-limited (429) or temporarily unavailable (5xx).

npm version npm downloads build release

Features

  • Configurable retries – Set the maximum number of attempts per request.
  • Per-request timeout – Abort requests that exceed a given duration.
  • Full jitter backoff – Exponential backoff with random jitter (AWS-style) between retries.
  • Custom retry predicate – Control which status codes trigger a retry (default: 429, 500, 502, 503, 504).
  • External cancellation – Pass an AbortSignal to cancel an in-flight request.
  • TypeScript – Exported types for RequestOptions and usage in TS/JS.

Installation

npm

npm install fetch-retrier

yarn

yarn add fetch-retrier

Usage

import { fetchRetrier, RequestOptions } from 'fetch-retrier';

const options: RequestOptions = {
  retries: 3,
  timeoutMs: 5000,
  baseBackoffMs: 1000,
  headers: {
    'Authorization': 'Bearer token',
  },
};

const response = await fetchRetrier('https://api.example.com/data', options);

if (response.ok) {
  const data = await response.json();
  // ...
}

Options

| Option | Type | Required | Description | |--------|------|----------|-------------| | retries | number | Yes | Maximum number of attempts (including the first request). | | timeoutMs | number | Yes | Timeout in milliseconds for each request. Requests are aborted when this is exceeded. | | baseBackoffMs | number | Yes | Base delay in milliseconds for backoff. Delay is capped at baseBackoffMs * 2^attempt and randomized (full jitter). | | headers | Record<string, string> | No | Headers to send with the request. | | signal | AbortSignal | No | Optional external abort signal. If already aborted, FetchRetrierAlreadyAbortedError is thrown. If aborted during an attempt, the request is aborted and retried until retries is exhausted. | | shouldRetry | (response: Response, body: string) => boolean | No | Custom predicate. Return true to retry on this response. Default: retry on status 429, 500, 502, 503, 504. |

Custom retry logic

const response = await fetchRetrier('https://api.example.com/data', {
  retries: 5,
  timeoutMs: 10000,
  baseBackoffMs: 500,
  shouldRetry: (res, body) => {
    // Retry on rate limit or server errors, or when body indicates "retry later"
    if ([429, 500, 502, 503].includes(res.status)) return true;
    if (res.status === 200 && body.includes('"retry": true')) return true;
    return false;
  },
});

Cancellation with AbortController

const controller = new AbortController();

setTimeout(() => controller.abort(), 250);

await fetchRetrier('https://api.example.com/data', {
  retries: 3,
  timeoutMs: 5000,
  baseBackoffMs: 250,
  signal: controller.signal,
});

Retry and error behavior

  • Success – If response.ok is true, the response is returned immediately.
  • Retriable failure – If the response is not OK and shouldRetry(response, body) returns true, the client waits (full jitter backoff) and retries until retries is exhausted. On the last attempt, FetchRetrierHttpError is thrown (includes status).
  • Non-retriable failure – If shouldRetry returns false, FetchRetrierHttpError is thrown immediately (e.g. message Non-retriable HTTP error: 404).
  • Timeout – If a request exceeds timeoutMs, it is aborted and retried (same backoff) until retries is exhausted; the final failure is FetchRetrierAbortError.
  • Network/TypeError – Network errors and related TypeErrors are retried with backoff; after the last attempt, FetchRetrierNetworkError is thrown with the original error as cause.
  • Already aborted signal – If signal is already aborted before an attempt starts, FetchRetrierAlreadyAbortedError is thrown immediately (no attempt is made).

Requirements

  • Node.js >= 20.0.0
  • Uses the global fetch (available in Node 18+).

License

This project is licensed under the (Apache-2.0) License.