Skip to content

kuitos/axios-extensions

Repository files navigation

axios-extensions

npm version build coverage npm downloads

Composable Axios adapter enhancers for cache, throttle, and retry.

Quick StartAPIMigrationnpm

axios-extensions gives you production-friendly request behavior without replacing Axios itself.

This README targets v4.x. Looking for older docs? See v3.1.7.

Migrating from v3? Read MIGRATION.md.

Table of Contents

Highlights

  • Composable by design: stack cache, throttle, and retry in one adapter pipeline.
  • 🧠 Sensible defaults: GET caching, GET-only throttling, and retry controls out of the box.
  • 🧩 TypeScript-ready: request config is module-augmented for feature flags and overrides.
  • 🪶 Lightweight: focused utilities with no framework lock-in.

Why axios-extensions

Enhancer What it does Typical use case
cacheAdapterEnhancer Request-level response caching Avoid duplicate reads for the same resource
throttleAdapterEnhancer Dedupe/throttle GET requests inside a time window Prevent burst requests during rapid UI interactions
retryAdapterEnhancer Retry failed requests with global/per-request overrides Improve resilience on flaky networks

These enhancers are designed to be composed together on top of Axios adapters.

Pick the right enhancer

If you want to... Use
Avoid duplicate reads and reuse response results cacheAdapterEnhancer
Collapse repeated GET requests in rapid bursts throttleAdapterEnhancer
Survive transient network/backend failures retryAdapterEnhancer

Version & Compatibility

Package Supported version
Node.js >= 18
axios >= 1.0.0

axios v0.19.0 is not supported due to an Axios custom config issue: axios/axios#2207

Installation

npm i axios-extensions
yarn add axios-extensions

Browser UMD build:

<!-- exposed as window['axios-extensions'] -->
<script src="https://unpkg.com/axios-extensions/dist/axios-extensions.min.js"></script>

Quick Start

Compose all three enhancers in one adapter:

import axios from 'axios';
import {
	cacheAdapterEnhancer,
	throttleAdapterEnhancer,
	retryAdapterEnhancer,
} from 'axios-extensions';

const adapter = retryAdapterEnhancer(
	throttleAdapterEnhancer(
		cacheAdapterEnhancer(axios.defaults.adapter!),
		{ threshold: 1000 },
	),
	{ times: 2 },
);

export const http = axios.create({
	baseURL: '/api',
	adapter,
});

Per-request overrides:

await http.get('/users', {
	forceUpdate: true,
	threshold: 3000,
	retryTimes: 3,
});

Common composition presets:

// 1) Cache only
const cacheOnly = cacheAdapterEnhancer(axios.defaults.adapter!);

// 2) Cache + throttle (great for list/search pages)
const cacheAndThrottle = throttleAdapterEnhancer(
	cacheAdapterEnhancer(axios.defaults.adapter!),
	{ threshold: 1000 },
);

// 3) Full resilience pipeline
const resilient = retryAdapterEnhancer(cacheAndThrottle, { times: 2 });

API

cacheAdapterEnhancer

When to use: cache requests (GET by default) and optionally customize cache strategy/key generation.

cacheAdapterEnhancer(adapter: NonNullable<AxiosRequestConfig['adapter']>, options?: {
	cacheable?: (config: AxiosRequestConfig) => boolean | ICacheLike<any>;
	keyGenerator?: (config: AxiosRequestConfig) => string;
	defaultCache?: ICacheLike<AxiosPromise>;
}): AxiosAdapter

Default behavior:

  • If config.cache is set, it is used as override
  • Otherwise GET requests are cached
  • Default cache store is new Cache({ ttl: 5 * 60 * 1000, max: 100 })

Common request options (module-augmented on AxiosRequestConfig):

  • cache?: boolean | ICacheLike<any>
  • forceUpdate?: boolean

Example: enable cache for GET by default, but force refresh per request:

await http.get('/users', { forceUpdate: true });

Example: opt-in cache only:

const adapter = cacheAdapterEnhancer(axios.defaults.adapter!, {
	cacheable: config => config.cache ?? false,
});

Example: cache GET + POST with a URL-only key (safe only when params/body do not affect response):

const adapter = cacheAdapterEnhancer(axios.defaults.adapter!, {
	cacheable: config => config.method === 'get' || config.method === 'post',
	keyGenerator: config => `${config.method}:${config.url}`,
});

config.url alone is only safe when query params/body do not change response semantics. Otherwise include params and (for non-GET) data in the key.

throttleAdapterEnhancer

When to use: dedupe GET requests triggered repeatedly within a short interval.

throttleAdapterEnhancer(adapter: NonNullable<AxiosRequestConfig['adapter']>, options?: {
	threshold?: number;
	cache?: ICacheLike<{ timestamp: number; value?: AxiosPromise }>;
}): AxiosAdapter

Default behavior:

  • Only affects GET requests
  • Requests within threshold (default 1000ms) reuse in-flight/previous promise
  • Non-GET requests pass through untouched

Request-level override:

  • threshold?: number on AxiosRequestConfig
await http.get('/users', { threshold: 3000 });

retryAdapterEnhancer

When to use: retry transient failures without rewriting request logic.

retryAdapterEnhancer(adapter: AxiosAdapter, options?: {
	times?: number;
}): AxiosAdapter

Default behavior:

  • Retries failed requests up to times (default 2)
  • Per-request override via retryTimes?: number
await http.get('/critical-endpoint', { retryTimes: 3 });

TypeScript Notes

axios-extensions augments Axios request types for:

  • cache
  • forceUpdate
  • threshold
  • retryTimes

When importing shared cache contracts in TypeScript, use type-only imports:

import type { ICacheLike } from 'axios-extensions';

If your project has strict interop settings, enabling these can improve import ergonomics:

  • esModuleInterop: true
  • allowSyntheticDefaultImports: true

Logging

Set process.env.LOGGER_LEVEL=info in Node-based development to enable internal info logging.

Development

npm run lint
npm test
npm run build

License

MIT

About

🍱 axios extensions lib, including throttle, cache, retry features etc...

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors