Registry / http-networking / fetch-smartly

fetch-smartly

JSON →
library1.0.2jsnpmunverified

Fetch Smartly is a zero-dependency, isomorphic HTTP client that wraps the native `fetch` API to provide production-grade resilience and intelligence for Node.js 18+, browsers, Cloudflare Workers, Deno, and Bun environments. It addresses common pain points of raw `fetch` by incorporating intelligent retry mechanisms with exponential backoff and jitter, respecting `Retry-After` headers, and automatically avoiding retries for 4xx client errors. The library offers a comprehensive typed error hierarchy, including `NetworkError`, `TimeoutError`, `HttpError`, and `RateLimitError`, enabling granular error handling via `instanceof` checks. Key features also include an automatic circuit breaker for failure isolation, request deduplication for identical concurrent GET/HEAD requests, and an offline queue with pluggable storage for replaying failed requests. Currently at version 1.0.2, the package is actively maintained with recent minor updates, distinguishing itself through its lightweight nature, strict TypeScript support, and robust, built-in resilience features.

npm install fetch-smartly
INSTALL
IMPORT
SIG · FETCH-SMARTLY
F
fetch-smartly
http-networkingjavascriptv1.0.2
Install
—
Import
—
Disk
—
Pass rate
0/ 6
Env Coverage0 / 6
glibc
18–22
musl
18–22
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18–226 runs
build_error
glibc
node 18–226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

fetchWithRetry
✓ import { fetchWithRetry } from 'fetch-smartly';
✗ const fetchWithRetry = require('fetch-smartly');
The library primarily uses ES modules; CommonJS imports may work but ESM is the idiomatic usage for modern Node.js environments (>=18).
HttpError, NetworkError, TimeoutError
✓ import { HttpError, NetworkError, TimeoutError } from 'fetch-smartly';
These are part of the custom typed error hierarchy for robust error handling using `instanceof`.
FetchSmartlyConfig
✓ import type { FetchSmartlyConfig } from 'fetch-smartly';
Import types separately using `import type` for clarity and to assist bundlers and type checkers.

This quickstart demonstrates how to use `fetchWithRetry` with intelligent retry logic, a request timeout, and a circuit breaker. It also shows how to handle the library's custom error hierarchy, including `HttpError`, `NetworkError`, `TimeoutError`, and `RateLimitError`, for robust error management.

import { fetchWithRetry, HttpError, NetworkError, TimeoutError, RateLimitError } from 'fetch-smartly'; async function fetchDataWithResilience() { try { const response = await fetchWithRetry({ url: 'https://api.github.com/users/octocat', // Example public API endpoint method: 'GET', retry: { attempts: 5, delay: 'exponential', // Use exponential backoff maxDelay: 5000, // Cap retry delay at 5 seconds shouldRetry: (error) => !(error instanceof HttpError && error.status >= 400 && error.status < 500), // Don't retry client errors }, timeout: 3000, // 3-second timeout for the request circuitBreaker: { threshold: 3, // Open after 3 consecutive failures resetTimeout: 10000, // Try to close after 10 seconds }, headers: { 'Content-Type': 'application/json', 'User-Agent': 'fetch-smartly-example', 'Authorization': `Bearer ${process.env.API_KEY ?? ''}` // Example of using an environment variable for auth } }); if (response.ok) { const data = await response.json(); console.log('Fetched data:', data); } else { console.error('HTTP Error:', response.status, response.statusText); } } catch (error) { if (error instanceof HttpError) { console.error(`Request failed with HTTP status ${error.status}: ${error.message}`); if (error instanceof RateLimitError) { console.warn(`Rate limited! Retry-After: ${error.retryAfter} seconds`); } } else if (error instanceof NetworkError) { console.error('Network connection error:', error.message); } else if (error instanceof TimeoutError) { console.error('Request timed out:', error.message); } else { console.error('An unexpected error occurred:', error); } } } fetchDataWithResilience();
Debug
Known issues
gotchaThe `offlineQueue` feature requires a pluggable storage mechanism (e.g., localStorage or a custom adapter). If no storage is configured, requests queued during offline periods will be lost upon application restart or page refresh.
fix
Implement and provide a storage adapter to the `offlineQueue` configuration. Refer to the official documentation for examples.
affects: >=1.0.0
gotchaWhile `fetch-smartly` aims for isomorphism, subtle differences in the underlying `fetch` implementation across various JavaScript runtimes (e.g., Node.js, browsers, Cloudflare Workers, Deno, Bun) may still lead to minor behavioral variances, especially concerning stream handling or error reporting specifics.
fix
Thoroughly test HTTP request patterns and error handling in all target environments where strict consistency is critical.
affects: >=1.0.0
gotchaThe default retry policy will *not* retry 4xx client errors by default (unless specifically overridden by `shouldRetry`). Ensure that non-idempotent requests (e.g., POST, PUT, PATCH, DELETE) are handled carefully if `shouldRetry` is customized, to prevent unintended side effects on repeated execution.
fix
Carefully configure the `retry.shouldRetry` callback for non-GET/HEAD requests, explicitly defining conditions under which a retry is safe and appropriate. Avoid retrying 4xx errors unless explicitly desired.
affects: >=1.0.0
Errors
Common errors & fixes
TypeError: fetch is not a function
The environment where `fetch-smartly` is running does not expose a global `fetch` API.
fix
Ensure you are running in a Node.js environment version 18 or higher, a modern browser, or a compatible serverless environment. If using an older Node.js, consider polyfilling `fetch` (though not recommended for `fetch-smartly` as it expects native behavior).
CircuitBreakerOpenError: Circuit breaker is currently open. Request was short-circuited.
The circuit breaker mechanism has detected a high rate of failures and has 'opened' to prevent further requests from overloading the failing service, protecting both the client and the service.
fix
This is expected behavior for a failing service. Wait for the `circuitBreaker.resetTimeout` to elapse, which will attempt to transition the circuit breaker to 'half-open' to test the service. Investigate and resolve the underlying service instability.
FetchSmartlyConfigError: 'url' is a required option in the fetchWithRetry configuration.
The `url` property, which specifies the target URL for the HTTP request, was omitted from the configuration object passed to `fetchWithRetry`.
fix
Always provide a valid URL string via the `url` property in the configuration object, e.g., `{ url: 'https://api.example.com/data' }`.
Upgrade
Version history
1.0.2latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
17 hits · last 30 days
node
14
OpenAI (training)
2
Resources
fetch-smartly — npm install fetch-smartly · libregistry