@ubay182/mini-super-fetch
v1.0.1
Published
Lightweight HTTP client with caching, deduplication, retry, interceptors, and upload support — inspired by axios and TanStack Query
Maintainers
Readme
mini-super-fetch
Lightweight HTTP client with caching, deduplication, retry, interceptors, and upload support — inspired by axios and TanStack Query.
Features
- ✅ Caching — stale-while-revalidate pattern (like TanStack Query)
- 🔄 Request Deduplication — identical requests share a single network call
- 🔁 Automatic Retry — configurable retries with exponential backoff
- 🔌 Interceptors — modify requests and responses on the fly
- 🛑 Abort Signal — cancel in-flight requests
- 📤 Upload — file upload with progress tracking
- 📦 TypeScript — full type safety
- 🪶 Zero dependencies — only ~3KB gzipped
Installation
npm install mini-super-fetchQuick Start
Without instance (default export)
import miniSuperFetch from "mini-super-fetch";
// URL harus lengkap (karena default instance gak punya baseURL)
const res = await miniSuperFetch.get("https://api.example.com/posts");
await miniSuperFetch.post("https://api.example.com/posts", { title: "Hello" });With configure() (custom defaults)
import { configure } from "mini-super-fetch";
// Create an instance — baseURL, headers, timeout otomatis di-set
const api = configure({
baseURL: "https://api.example.com",
timeout: 10000,
retries: 3,
});
const res = await api.get("/posts");
const res = await api.post("/posts", { title: "Hello" });API Reference
configure(config)
Create a new instance with custom defaults. Each instance has its own cache and interceptors.
import { configure } from "mini-super-fetch";
const api = configure({
baseURL: "https://api.example.com",
timeout: 10000,
retries: 3,
retryDelay: 1000,
retryOnStatus: [500, 502, 503, 504],
staleTime: 0, // how long data is "fresh" (ms)
gcTime: 300000, // how long before cache is garbage collected (ms)
});HTTP Methods
api.get<T>("/posts", { params: { _limit: 10 }, cache: { staleTime: 30_000 } });
api.post<T>("/posts", { title: "Hello" });
api.put<T>("/posts/1", { title: "Updated" });
api.patch<T>("/posts/1", { title: "Patched" });
api.delete<T>("/posts/1");
api.upload<T>("/upload", file, {
fields: { userId: 1 },
onProgress: (pct) => console.log(pct),
});Cache Options
api.get("/posts", {
cache: {
staleTime: 30_000, // data fresh for 30s — next get() returns instant from cache
gcTime: 60_000, // cache removed after 60s
forceFetch: false, // skip cache, always fetch
onSuccess: (data) => console.log("background update", data),
},
});Stale-While-Revalidate (SWR)
When cache is stale, get() returns cached data instantly and fetches fresh data in the background. The onSuccess callback fires when background fetch completes.
// First call: fetches from network, caches for 30s
const res = await api.get("/posts", { cache: { staleTime: 30_000 } });
// After 30s, cache is stale — next call returns cache instantly + revalidates in background
const res = await api.get("/posts", {
cache: { staleTime: 30_000, onSuccess: (data) => console.log("updated!") },
});Interceptors
// Request interceptor
const removeReq = api.onRequest((config) => {
config.headers = { ...config.headers, Authorization: "Bearer token" };
return config;
});
// Response interceptor
const removeRes = api.onResponse((response) => {
console.log(`${response.status} ${response.config.url}`);
return response;
});
// Remove when done
removeReq();
removeRes();Cache Management
// Prefetch — warm up cache before user needs it
await api.prefetch("/posts", { cache: { staleTime: 60_000 } });
// Invalidate specific cache
api.invalidateCache("GET:/posts");
api.invalidateCache("GET:/posts", { exact: false }); // prefix match
api.invalidateCache(); // clear all
// Clear everything (cache + in-flight requests)
api.clear();Abort Signal
const controller = new AbortController();
api.get("/posts", { signal: controller.signal });
// Cancel request
controller.abort();License
MIT
