A lightweight and powerful alternative to Axios, Fetch, or node-fetch. Not just a wrapper β a true evolution.
π Why Fetchless?
Most HTTP libraries like axios
or fetch
do the bare minimum: send a request and return a response.
But modern web applications need more: performance, smart caching, robustness, resilience, and most of all... simplicity.
Fetchless delivers all of this with an HTTP API designed for 2025 β combining lightness, intelligence, and automation.
βοΈ Core Features
- β Efficient Caching: Stores HTTP responses to reduce network calls and boost speed.
- β
Multiple Cache Strategies: Supports
cache-first
,network-first
, andstale-while-revalidate
modes. - β TypeScript Support: Fully typed API for maximum reliability.
- β Ultra Lightweight: Minimal footprint with almost no dependencies.
- β Easy Integration: Works out of the box with any JS or TS project.
π₯ Advanced Features
- πΉ Prefetching: Preload resources in the background.
- πΉ Request Deduplication: Automatically combines identical concurrent requests.
- πΉ Interceptors: Middleware to modify requests/responses on the fly.
- πΉ Retry with Backoff: Retries failed requests with exponential delay.
- πΉ Persistent Cache: Uses
localStorage
to keep cache across sessions. - πΉ Abortable Requests: Easily cancel unnecessary requests.
- πΉ React Hooks: Built-in hooks to integrate with modern React apps.
π§ What Makes Fetchless Unique
- π‘οΈ Best practices by default: timeouts, error handling, cache control.
- 𧬠Network-aware logic: smart cache modes, deduplication, aborts.
- β‘ Full TypeScript + React support.
- π¦ Smart caching: avoid redundant calls, even between sessions.
- βΊ Automatic retries when the network fails.
π§ͺ Code Examples
β¨ Basic Usage
import { get } from 'fetchless';
get('https://api.example.com/data')
.then(response => console.log(response.data));
π§ Creating a Custom Client
import { createAdvancedClient } from 'fetchless';
const client = createAdvancedClient({
persistCache: true,
dedupeRequests: true,
retryOptions: {
maxRetries: 3,
backoffFactor: 300,
retryStatusCodes: [408, 429, 500, 502, 503, 504]
}
});
βοΈ Using Interceptors
client.addRequestInterceptor((url, config) => [
url,
{
...config,
headers: {
...config?.headers,
'Authorization': `Bearer ${getToken()}`
}
}
]);
client.addResponseInterceptor((response) => ({
...response,
data: transformData(response.data)
}));
β Prefetching
import { prefetch } from 'fetchless';
prefetch('https://api.example.com/future-data');
π Abortable Requests
import { abortableGet } from 'fetchless';
const { promise, abort } = abortableGet('https://api.example.com/large-data');
promise.then(response => console.log(response.data));
abort();
π React Integration
import { useFetchless } from 'fetchless';
function UserProfile({ userId }) {
const { data, loading, error } = useFetchless(`https://api.example.com/users/${userId}`);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return (
<div>
<h1>{data.name}</h1>
<p>{data.email}</p>
</div>
);
}
π Cache Statistics
import { defaultClient } from 'fetchless';
const stats = defaultClient.getStats();
console.log(stats);
// { hits: 5, misses: 2, ratio: 0.71, size: 7 }
defaultClient.clearCache();
π Learn More
β¨ Installation
npm install fetchless
π Call to Action
Try Fetchless today.
Open an issue.
Star the project.
And never write rawfetch
again β€οΈ.
π DEV.to Tags
#javascript #typescript #webdev #react #fetchless #opensource
Top comments (0)