axios-retry vs fetch-retry vs requestretry vs retry-axios vs retry-request vs superagent-retry
Implementing Robust HTTP Retry Logic in JavaScript Applications
axios-retryfetch-retryrequestretryretry-axiosretry-requestsuperagent-retrySimilar Packages:

Implementing Robust HTTP Retry Logic in JavaScript Applications

This comparison evaluates six npm packages designed to add automatic retry capabilities to HTTP requests. These tools address transient network failures, server timeouts, and rate limiting by automatically re-sending failed requests based on configurable strategies. While they share a common goal, they differ significantly in their underlying HTTP clients (Axios, Fetch, Request, Superagent), maintenance status, and integration patterns. Some are modern, actively maintained plugins for current standards, while others are legacy solutions tied to deprecated libraries. Understanding these distinctions is critical for building resilient frontend and Node.js applications without introducing technical debt.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
axios-retry8,646,4622,01633.6 kB582 years agoApache-2.0
fetch-retry5,177,21131755.2 kB62 years agoMIT
requestretry034656.5 kB1310 months agoMIT
retry-axios050964.9 kB04 months agoApache-2.0
retry-request03,19216.3 kB5923 days agoMIT
superagent-retry084-1010 years ago-

HTTP Retry Libraries: Architecture, Maintenance, and Real-World Usage

Building resilient applications means expecting failure. Networks drop packets, servers timeout, and APIs rate-limit users. To handle these transient errors, developers use retry libraries that automatically re-attempt failed HTTP requests. The JavaScript ecosystem offers several options, but they are not interchangeable. They differ by the HTTP client they support, their maintenance status, and how they integrate into your codebase.

This analysis breaks down six popular packages. We will look at which ones are safe for modern development, which are deprecated, and exactly how to implement them in real scenarios.

⚠️ Critical Warning: The Deprecated Ecosystem

Before writing any code, we must address the elephant in the room. Two of the packages in this comparison—requestretry and retry-request—are built on top of the request library.

The request library was officially deprecated in February 2020. It no longer receives security updates or bug fixes. Consequently, you should not use requestretry or retry-request in any new project.

// ❌ LEGACY: Do not use in new projects
const request = require('requestretry');

request({
    url: 'https://api.example.com/data',
    maxAttempts: 3,
    retryDelay: 2000
}, function (err, response, body) {
    // Handling logic here
});

Using these libraries forces your application to depend on unmaintained code. If a security vulnerability is discovered in the underlying request package, your application is exposed. For all new development, migrate to solutions based on Axios or the native Fetch API.

🚀 Modern Standards: Axios and Fetch

For contemporary frontend and Node.js development, the choice is effectively between axios-retry, retry-axios, and fetch-retry. These libraries wrap modern, maintained HTTP clients.

1. Axios-Based Solutions (axios-retry vs retry-axios)

Axios remains the most popular HTTP client for complex applications due to its rich feature set, including interceptors, request cancellation, and automatic JSON transformation. Two packages add retry logic to Axios: axios-retry and retry-axios.

axios-retry is the dominant choice. It is widely adopted, well-documented, and offers a flexible API for defining retry conditions. It attaches directly to the Axios instance via interceptors.

// ✅ RECOMMENDED: axios-retry
import axios from 'axios';
import axiosRetry from 'axios-retry';

const client = axios.create({ baseURL: 'https://api.example.com' });

axiosRetry(client, {
  retries: 3,
  retryDelay: (retryCount) => {
    return retryCount * 1000; // Linear backoff
  },
  retryCondition: (error) => {
    // Retry on 5xx errors or network errors
    return axiosRetry.isNetworkOrIdempotentRequestError(error) || error.response?.status === 503;
  }
});

// Usage is transparent; retries happen automatically
client.get('/users');

retry-axios also provides retry functionality for Axios but is less commonly used in the broader community. It follows a similar interceptor pattern but often lacks the extensive configuration options and community examples found in axios-retry.

// ⚠️ ALTERNATIVE: retry-axios
import axios from 'axios';
import { attach } from 'retry-axios';

attach({
  axios: axios,
  retryConfig: {
    retries: 3,
    retryDelay: 1000,
    statusCodes: [500, 502, 503, 504]
  }
});

// Usage
axios.get('/users');

Selection Guideline: Unless you have a specific requirement that axios-retry cannot meet, default to axios-retry. Its larger community ensures better long-term support and more available troubleshooting resources.

2. Native Fetch Solutions (fetch-retry)

The native fetch API is now available in all modern browsers and recent versions of Node.js (v18+). It is lightweight and standard-compliant but lacks built-in retry logic. fetch-retry fills this gap by wrapping the native function.

This is the best choice for projects aiming to reduce bundle size by avoiding heavy HTTP clients like Axios.

// ✅ MODERN: fetch-retry
import fetchRetry from 'fetch-retry';

// Wrap the native fetch
const fetchWithRetry = fetchRetry(fetch);

fetchWithRetry('https://api.example.com/users', {
  retries: 3,
  retryDelay: (attempt) => Math.pow(2, attempt) * 1000, // Exponential backoff
  retryOn: (attempt, error, response) => {
    // Retry if status is 503 or if a network error occurred
    if (attempt >= 3) return false;
    if (response && response.status === 503) return true;
    if (error) return true;
    return false;
  }
})
.then(response => response.json())
.then(data => console.log(data));

Selection Guideline: Use fetch-retry if you are building modern web apps, serverless functions, or microservices where minimizing dependencies is a priority. It pairs perfectly with node-fetch for older Node.js environments.

🕰️ Legacy Superagent Support (superagent-retry)

Superagent was once a leading HTTP client, known for its fluent API. While its usage has declined in favor of Axios and Fetch, some legacy enterprise systems still rely on it. superagent-retry is a plugin specifically designed for this client.

// ⚠️ LEGACY MAINTENANCE ONLY: superagent-retry
import request from 'superagent';
import requestRetry from 'superagent-retry';

requestRetry(request);

request
  .get('https://api.example.com/users')
  .retry(3) // Set retry count
  .end((err, res) => {
    if (err) throw err;
    console.log(res.body);
  });

Selection Guideline: Only use superagent-retry if you are maintaining an existing codebase that already uses Superagent. Do not introduce Superagent into a new project; the ecosystem momentum has clearly shifted to Axios and Fetch.

🧠 Deep Dive: Retry Strategies and Backoff

A key differentiator between these libraries is how they handle backoff strategies. Blindly retrying immediately can overwhelm a struggling server. Effective libraries implement exponential backoff—waiting longer between each attempt.

All modern packages discussed (axios-retry, fetch-retry) allow custom delay functions. Here is how they compare in implementation:

Exponential Backoff Implementation

In axios-retry: You define a retryDelay function that receives the retry count.

axiosRetry(axiosClient, {
  retryDelay: (retryCount) => {
    // Wait 1s, then 2s, then 4s...
    return Math.pow(2, retryCount) * 1000;
  }
});

In fetch-retry: The retryDelay option works similarly, accepting the attempt number.

fetchWithRetry(url, {
  retryDelay: (attempt) => {
    // Wait 1s, then 2s, then 4s...
    return Math.pow(2, attempt) * 1000;
  }
});

In superagent-retry: Superagent's plugin often uses a simpler configuration or relies on the underlying library's timeout mechanisms, though custom delays can sometimes be chained.

request
  .get(url)
  .retry(3, (err, res) => {
    if (err) return 2000; // Fixed delay or logic based on error
    return 0;
  });

Conditional Retries

Not all errors should trigger a retry. Retrying a 401 Unauthorized or 404 Not Found is useless. You must configure conditions carefully.

axios-retry provides a helper isNetworkOrIdempotentRequestError which automatically handles common safe-to-retry scenarios (like GET requests failing due to network issues).

retryCondition: (error) => {
  return axiosRetry.isNetworkOrIdempotentRequestError(error) || error.code === 'ECONNRESET';
}

fetch-retry requires you to manually inspect the response object or catch block, giving you full control but requiring more boilerplate.

retryOn: (attempt, error, response) => {
  if (error || (response && response.status >= 500)) {
    return true;
  }
  return false;
}

📊 Summary Comparison

PackageBase ClientMaintenance StatusBest Use Case
axios-retryAxios✅ ActiveStandard choice for Axios projects
fetch-retryFetch API✅ ActiveModern, lightweight, dependency-free
retry-axiosAxios⚠️ Low ActivityAlternative Axios interceptor
superagent-retrySuperagent⚠️ LegacyMaintaining old Superagent codebases
requestretryRequest❌ DeprecatedDo Not Use
retry-requestRequest❌ DeprecatedDo Not Use

💡 Final Recommendation

For new projects, the decision is straightforward:

  1. If you need a full-featured HTTP client with interceptors and broad browser support: Use Axios paired with axios-retry.
  2. If you prefer native standards, minimal bundle size, or are working in Serverless/Edge environments: Use native Fetch paired with fetch-retry.

Avoid requestretry and retry-request entirely. They represent a bygone era of JavaScript development and pose unnecessary risks. By choosing actively maintained libraries, you ensure your application remains secure, performant, and easy to debug for years to come.

How to Choose: axios-retry vs fetch-retry vs requestretry vs retry-axios vs retry-request vs superagent-retry

  • axios-retry:

    Choose axios-retry if your project already uses Axios as its primary HTTP client. It is the industry standard for Axios-based retry logic, offering robust exponential backoff, custom retry conditions, and seamless integration via interceptors. It is actively maintained and works in both browser and Node.js environments.

  • fetch-retry:

    Choose fetch-retry if you are using the native fetch API or node-fetch and want a lightweight, dependency-free solution. It wraps the native fetch function to add retry logic without requiring a full client replacement, making it ideal for modern stacks aiming to minimize bundle size.

  • requestretry:

    Do NOT choose requestretry for new projects. It depends on the request library, which has been officially deprecated since 2020. Using this package introduces significant security risks and technical debt. Migrate to axios-retry or fetch-retry instead.

  • retry-axios:

    Choose retry-axios only if you need a very specific, minimal interceptor implementation that differs slightly from axios-retry. However, for most use cases, axios-retry is more feature-complete and better documented. This package is less common and may have a smaller community support footprint.

  • retry-request:

    Do NOT choose retry-request for new projects. Like requestretry, it relies on the deprecated request library. It is strictly legacy software and should be avoided in favor of modern alternatives based on Axios or native Fetch.

  • superagent-retry:

    Choose superagent-retry only if you are maintaining an existing legacy codebase that relies heavily on Superagent. For new development, prefer axios-retry or fetch-retry, as Superagent has seen significantly reduced adoption compared to Axios and native Fetch in recent years.

README for axios-retry

axios-retry

Node.js CI

Axios plugin that intercepts failed requests and retries them whenever possible.

Installation

npm install axios-retry

Usage

// CommonJS
// const axiosRetry = require('axios-retry').default;

// ES6
import axiosRetry from 'axios-retry';

axiosRetry(axios, { retries: 3 });

axios.get('http://example.com/test') // The first request fails and the second returns 'ok'
  .then(result => {
    result.data; // 'ok'
  });

// Exponential back-off retry delay between requests
axiosRetry(axios, { retryDelay: axiosRetry.exponentialDelay });

// Liner retry delay between requests
axiosRetry(axios, { retryDelay: axiosRetry.linearDelay() });

// Custom retry delay
axiosRetry(axios, { retryDelay: (retryCount) => {
  return retryCount * 1000;
}});

// Works with custom axios instances
const client = axios.create({ baseURL: 'http://example.com' });
axiosRetry(client, { retries: 3 });

client.get('/test') // The first request fails and the second returns 'ok'
  .then(result => {
    result.data; // 'ok'
  });

// Allows request-specific configuration
client
  .get('/test', {
    'axios-retry': {
      retries: 0
    }
  })
  .catch(error => { // The first request fails
    error !== undefined
  });

Note: Unless shouldResetTimeout is set, the plugin interprets the request timeout as a global value, so it is not used for each retry but for the whole request lifecycle.

Options

NameTypeDefaultDescription
retriesNumber3The number of times to retry before failing. 1 = One retry after first failure
retryConditionFunctionisNetworkOrIdempotentRequestErrorA callback to further control if a request should be retried. By default, it retries if it is a network error or a 5xx error on an idempotent request (GET, HEAD, OPTIONS, PUT or DELETE).
shouldResetTimeoutBooleanfalseDefines if the timeout should be reset between retries
retryDelayFunctionfunction noDelay() { return 0; }A callback to further control the delay in milliseconds between retried requests. By default there is no delay between retries. Another option is exponentialDelay (Exponential Backoff) or linearDelay. The function is passed retryCount and error.
onRetryFunctionfunction onRetry(retryCount, error, requestConfig) { return; }A callback to notify when a retry is about to occur. Useful for tracing and you can any async process for example refresh a token on 401. By default nothing will occur. The function is passed retryCount, error, and requestConfig.
onMaxRetryTimesExceededFunctionfunction onMaxRetryTimesExceeded(error, retryCount) { return; }After all the retries are failed, this callback will be called with the last error before throwing the error.
validateResponseFunction | nullnullA callback to define whether a response should be resolved or rejected. If null is passed, it will fallback to the axios default (only 2xx status codes are resolved).

Testing

Clone the repository and execute:

npm test

Contribute

  1. Fork it: git clone https://github.com/softonic/axios-retry.git
  2. Create your feature branch: git checkout -b feature/my-new-feature
  3. Commit your changes: git commit -am 'Added some feature'
  4. Check the build: npm run build
  5. Push to the branch: git push origin my-new-feature
  6. Submit a pull request :D