Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@alwatr/fetch

Alwatr3.5kMPL-2.06.0.16TypeScript support: included

@alwatr/fetch is an enhanced, lightweight, and dependency-free wrapper for the native fetch API. It provides modern features like caching strategies, request retries, timeouts, and intelligent duplicate request handling, all in a compact package.

alwatr, api, browser, cache, cross-platform, ECMAScript, esm, fetch, javascript, module, nanolib, node, nodejs, request, retry, timeout, typescript, util, utility, utils

readme

@alwatr/fetch

@alwatr/fetch

@alwatr/fetch is an enhanced, lightweight, and dependency-free wrapper for the native fetch API. It provides modern features like caching strategies, request retries, timeouts, and intelligent duplicate request handling, all in a compact package.

It's designed to be a drop-in replacement for the standard fetch to instantly upgrade your application's network layer.

Key Features

  • Retry Pattern: Automatically retries failed requests on timeouts or server errors (5xx).
  • Request Timeout: Aborts requests that take too long to complete.
  • Duplicate Handling: Prevents sending identical parallel requests, returning a single response for all callers.
  • Caching Strategies: Leverages the browser's Cache API with strategies like stale_while_revalidate.
  • Simplified API: Send JSON and URL parameters with ease using bodyJson and queryParams.
  • TypeScript First: Written entirely in TypeScript for a great developer experience.

Installation

Install the package using your preferred package manager:

# npm
npm i @alwatr/fetch

# yarn
yarn add @alwatr/fetch

# pnpm
pnpm add @alwatr/fetch

Quick Start

Import the fetch function and use it just like you would the native fetch. It accepts a URL and an options object with several powerful enhancements.

import {fetch} from '@alwatr/fetch';

async function fetchProducts() {
  try {
    console.log('Fetching product list...');
    const response = await fetch('/api/products', {
      queryParams: {limit: 10, category: 'electronics'},
      cacheStrategy: 'stale_while_revalidate',
      timeout: '5s', // Use string duration
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    console.log('Products:', data);
  } catch (error) {
    console.error('Failed to fetch products:', error);
  }
}

fetchProducts();

API and Options

The fetch function takes a url string and an options object. The options object extends the standard RequestInit and adds several custom options for enhanced control.

Option Type Default Description
method HttpMethod 'GET' The HTTP request method.
headers HttpRequestHeaders {} An object representing the request's headers.
timeout Duration 8_000 (8s) Request timeout in milliseconds or as a duration string (e.g., '5s'). Set to 0 to disable.
retry number 3 Number of retries if the request fails with a server error (5xx) or times out.
retryDelay Duration 1_000 (1s) Delay between retry attempts in milliseconds or as a duration string.
removeDuplicate 'never' | 'always' | 'until_load' | 'auto' 'never' Strategy for handling identical parallel requests. body is included for uniqueness.
cacheStrategy 'network_only' | 'network_first' | ... 'network_only' Caching strategy using the browser's Cache API.
cacheStorageName string 'fetch_cache' Custom name for the CacheStorage instance.
revalidateCallback (response: Response) => void undefined Callback executed with the new response when using stale_while_revalidate strategy.
bodyJson Json undefined A JavaScript object sent as the request body. Sets Content-Type to application/json.
queryParams Dictionary undefined An object of query parameters appended to the URL.
bearerToken string undefined A bearer token added to the Authorization header.
alwatrAuth {userId: string; userToken: string} undefined Alwatr-specific authentication credentials.

... and all other standard RequestInit properties like signal, credentials, etc.


Features in Detail

Query Parameters

The queryParams option simplifies adding search parameters to your request URL.

// This will make a GET request to:
// /api/users?page=2&sort=asc
const response = await fetch('/api/users', {
  queryParams: {
    page: 2,
    sort: 'asc',
  },
});

JSON Body

Use bodyJson to send a JavaScript object as a JSON payload. The Content-Type header is automatically set to application/json.

// This will make a POST request to /api/orders with a JSON body
const response = await fetch('/api/orders', {
  method: 'POST',
  bodyJson: {
    productId: 'xyz-123',
    quantity: 2,
  },
});

Timeout

Set a timeout for your requests. If the request takes longer than the specified duration, it will be aborted, and the promise will reject with a fetch_timeout error.

await fetch('/api/slow-endpoint', {
  timeout: '2.5s', // You can use duration strings
});

Retry Pattern

The fetch operation will automatically retry on server errors (5xx status codes) or timeouts.

// Retry up to 5 times, with a 2-second delay between each attempt
await fetch('/api/flaky-service', {
  retry: 5,
  retryDelay: '2s',
});

Duplicate Request Handling

The removeDuplicate option prevents multiple identical requests from being sent simultaneously. The uniqueness of a request is determined by its method, URL, and body.

  • 'never' (default): Does nothing.
  • 'until_load': Caches the Promise of a request until it resolves. Subsequent identical requests will receive a clone of the first response.
  • 'always': Caches the response indefinitely (for the lifetime of the application).
  • 'auto': Uses 'until_load' if the Cache API is available, otherwise 'always'.
// Both calls will result in only ONE network request.
// The second call will receive the response from the first.
const [res1, res2] = await Promise.all([
  fetch('/api/data', {removeDuplicate: 'until_load'}),
  fetch('/api/data', {removeDuplicate: 'until_load'}),
]);

Cache Strategies

Leverage the browser's Cache API with cacheStrategy.

  • 'network_only' (default): Standard fetch behavior; no caching.
  • 'cache_first': Serves from cache if available. Otherwise, fetches from the network and caches the result.
  • 'network_first': Fetches from the network first. If the network fails, it falls back to the cache.
  • 'stale_while_revalidate': The fastest strategy. It serves stale content from the cache immediately while sending a network request in the background to update the cache for the next time.
// Serve news from cache instantly, but update it in the background for the next visit.
const response = await fetch('/api/news', {
  cacheStrategy: 'stale_while_revalidate',
  revalidateCallback: (freshResponse) => {
    console.log('Cache updated with fresh data!');
    // You can use freshResponse to update the UI if needed
  },
});

Authentication

Easily add authentication headers with bearerToken or the alwatrAuth scheme.

// Using a Bearer Token
await fetch('/api/secure/data', {
  bearerToken: 'your-jwt-token-here',
});

// Using Alwatr's authentication scheme
await fetch('/api/secure/data', {
  alwatrAuth: {
    userId: 'user-id',
    userToken: 'user-auth-token',
  },
});

Sponsors

The following companies, organizations, and individuals support Nanolib's ongoing maintenance and development. Become a Sponsor to get your logo on our README and website.

Contributing

Contributions are welcome! Please read our contribution guidelines before submitting a pull request.

changelog

Change Log

All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.

6.0.16 (2025-10-06)

🔗 Dependencies update

  • bump the npm-dependencies group with 4 updates (9825815)

6.0.15 (2025-09-27)

🧹 Miscellaneous Chores

  • exclude test files from package distribution (86f4f2f)

6.0.14 (2025-09-22)

Note: Version bump only for package @alwatr/fetch

6.0.13 (2025-09-22)

Note: Version bump only for package @alwatr/fetch

6.0.12 (2025-09-21)

Note: Version bump only for package @alwatr/fetch

6.0.11 (2025-09-20)

🐛 Bug Fixes

  • add sideEffects property to package.json files for better tree-shaking (c7b9e74)
  • add sideEffects property to package.json files for better tree-shaking (e8402c4)
  • remove unnecessary pure annotations (adeb916)

🧹 Miscellaneous Chores

  • remove duplicate sideEffects property from multiple package.json files (b123f86)

6.0.10 (2025-09-19)

Note: Version bump only for package @alwatr/fetch

6.0.9 (2025-09-19)

Note: Version bump only for package @alwatr/fetch

6.0.8 (2025-09-15)

Note: Version bump only for package @alwatr/fetch

6.0.7 (2025-09-14)

Note: Version bump only for package @alwatr/fetch

6.0.6 (2025-09-13)

Note: Version bump only for package @alwatr/fetch

6.0.5 (2025-09-13)

🧹 Miscellaneous Chores

  • remove package-tracer dependency and related code from fetch package (96fe4e9)

6.0.4 (2025-09-13)

Note: Version bump only for package @alwatr/fetch

6.0.3 (2025-09-09)

Note: Version bump only for package @alwatr/fetch

6.0.2 (2025-09-08)

Note: Version bump only for package @alwatr/fetch

6.0.1 (2025-09-06)

🔨 Code Refactoring

  • update bodyJson type definition to use JsonValue for consistency (ca18953)

6.0.0 (2025-09-06)

⚠ BREAKING CHANGES

  • Removed fetchJson; refactored fetch to accept url as a separate parameter, matching the web standard API.

🐛 Bug Fixes

  • include request body in cache key for duplicate request handling (a891ceb)
  • update query parameter encoding in fetch function for proper URL formatting (ae30c1e)

🔨 Code Refactoring

  • enhance FetchOptions type and improve fetch function handling (a35e8e4)
  • enhance logging in fetch and cache strategy functions for better traceability (db0c51b)
  • improve documentation for fetch options and caching strategies (d114290)
  • rename FetchOptions_ to AlwatrFetchOptions_ for consistency (978947a)
  • rewrite fetch module (d245cce)
  • update fetch calls to use consistent parameters and improve response handling (49436e6)
  • update FetchOptions interface to enforce required properties (4423740)
  • update FetchOptions type to AlwatrFetchOptions_ for consistency (6c1ff26)

5.6.7 (2025-09-05)

🔗 Dependencies update

  • update jest to version 30.1.3 and @types/node to version 22.18.1 (754212b)

5.6.6 (2025-09-01)

🔗 Dependencies update

  • update lerna-lite dependencies to version 4.7.3 and jest to 30.1.2 (95d7870)

5.6.5 (2025-08-23)

Note: Version bump only for package @alwatr/fetch

5.6.4 (2025-08-23)

🐛 Bug Fixes

  • update license from AGPL-3.0-only to MPL-2.0 (d20968e)
  • update package versions in multiple package.json files (7638b1c)

🔨 Code Refactoring

  • Updated all package.json files in the project to change dependency version specifiers from "workspace:^" to "workspace:*" for consistency and to allow for more flexible version resolution. (db6a4f7)

🧹 Miscellaneous Chores

  • reformat all package.json files (ceda45d)

🔗 Dependencies update

  • update TypeScript and Jest versions across all packages to improve compatibility and performance (31baf36)

5.6.3 (2025-08-23)

Code Refactoring

  • Updated all package.json files in the project to change dependency version specifiers from "workspace:^" to "workspace:*" for consistency and to allow for more flexible version resolution. (db6a4f7) by @alimd

5.6.2 (2025-04-20)

Note: Version bump only for package @alwatr/fetch

5.6.1 (2025-04-15)

Note: Version bump only for package @alwatr/fetch

5.6.0 (2025-04-15)

Features

  • fetchJson: include responseText in error logging for better debugging (168aa1c) by @alimd

Bug Fixes

  • fetchJson: update return type of fetchJson to be more generic (9db5234) by @alimd

5.5.2 (2025-04-01)

Note: Version bump only for package @alwatr/fetch

5.5.1 (2025-03-18)

Note: Version bump only for package @alwatr/fetch

5.5.0 (2025-03-06)

Miscellaneous Chores

  • update username casing in changelog entries (9722ac9) by @

Dependencies update

  • bump the development-dependencies group across 1 directory with 11 updates (720c395) by @dependabot[bot]

5.4.0 (2025-02-18)

5.3.0 (2025-02-03)

Miscellaneous Chores

Dependencies update

  • bump the development-dependencies group across 1 directory with 11 updates (cb79d07) by @
  • update typescript and @types/node to version 5.7.3 and 22.13.0 respectively across multiple packages (ddab05b) by @

5.2.1 (2024-11-07)

Bug Fixes

  • fetch: refine error handling in fetchJson to improve response error structure (2942563) by @

5.2.0 (2024-11-06)

Features

  • fetch: improve error handling for fetch responses and JSON parsing (8692bb1) by @

5.0.0 (2024-11-02)

⚠ BREAKING CHANGES

  • To simplify version management and ensure consistency, all nanolib packages now use the same version as @alwatr/nanolib. This may require updates to your project's dependencies.

Code Refactoring

  • use the same version as @alwatr/nanolib (60eb860) by @

5.3.0 (2025-02-03)

Miscellaneous Chores

  • edit README (3860b3d) by @ArmanAsadian

Dependencies update

  • bump the development-dependencies group across 1 directory with 11 updates (cb79d07) by @dependabot[bot]
  • update typescript and @types/node to version 5.7.3 and 22.13.0 respectively across multiple packages (ddab05b) by @alimd

5.2.1 (2024-11-07)

Bug Fixes

  • fetch: refine error handling in fetchJson to improve response error structure (2942563) by @

5.2.0 (2024-11-06)

Features

  • fetch: improve error handling for fetch responses and JSON parsing (8692bb1) by @alimd

5.0.0 (2024-11-02)

⚠ BREAKING CHANGES

  • To simplify version management and ensure consistency, all nanolib packages now use the same version as @alwatr/nanolib. This may require updates to your project's dependencies.
  • fetch: queryParametters renamed to queryParams
  • fetch: remove serviceRequest

Co-authored-by: Ali Mihandoost ali@mihandoost.com

Features

  • fetch: alwatrAuth (28e365c) by @
  • fetch: fetch json (b089f12) by @
  • fetch: move from last repo (4b86bb5) by @
  • fetch: Update fetch type definitions with document (38398cc) by @
  • fetch: use @alwatr/http-primer for types and http codes (6fe993a) by @
  • use package-tracer (cc3c5f9) by @

Bug Fixes

  • all dependeny topology (1c17f34) by @
  • exported types by add .js extensions to all imports (fc3d83e) by @
  • fetch: better error handling on handleRetryPattern_ when user is offline (b867f30) by @
  • fetch: remove unused import from fetch core module (28ec726) by @

Code Refactoring

  • fetch: handle fetchJson error responses properly (ae8fe24) by @
  • fetch: review and update everything (61ec38b) by @
  • fetch: separate core files (c7e6b09) by @
  • fetch: update fetch package to use @alwatr/parse-duration for timeout and retryDelay durations (1108c54) by @
  • fetch: update HTTP headers content-type to use MimeTypes constant (c3862fc) by @
  • fetch: Update logger import and initialization (1f0451c) by @
  • fetch: update query parameters handling (939b3d5) by @
  • fetch: use new DictionaryReq type (a8149cf) by @
  • prevent side-effects (01e00e1) by @
  • update Dictionary type definitions (c94cbc4) by @
  • use new global-this package (42510b9) by @
  • use new type-helper global types and remove all import types (08b5d08) by @
  • use the same version as @alwatr/nanolib (60eb860) by @
  • wait: rename package to delay (cf8c45c) by @

Miscellaneous Chores

  • deps: update (1a45030) by @
  • fetch: change the license to AGPL-3.0 (edf9069) by @
  • include LICENSE and LEGAL files to publish (09f366f) by @
  • Update build and lint scripts (392d0b7) by @
  • Update package.json exports for @alwatr packages (dacb362) by @

Dependencies update

  • bump @types/node (3d80fed) by @
  • bump the development-dependencies group across 1 directory with 10 updates (9ed98ff) by @
  • bump the development-dependencies group with 10 updates (fa4aaf0) by @
  • upd (451d025) by @
  • update (c36ed50) by @
  • update all (53342f6) by @
  • update all (a828818) by @
  • update all dependencies (1e0c30e) by @
  • update all dependencies (0e908b4) by @
  • upgrade (6dbd300) by @

4.2.1 (2024-11-02)

Note: Version bump only for package @alwatr/fetch

4.2.0 (2024-10-28)

Features

  • fetch: use @alwatr/http-primer for types and http codes (6fe993a) by @alimd

Code Refactoring

  • fetch: update HTTP headers content-type to use MimeTypes constant (c3862fc) by @alimd

4.1.7 (2024-10-25)

Note: Version bump only for package @alwatr/fetch

4.1.6 (2024-10-12)

Note: Version bump only for package @alwatr/fetch

4.1.5 (2024-10-11)

Code Refactoring

  • prevent side-effects (01e00e1) by @mohammadhonarvar
  • use new global-this package (42510b9) by @mohammadhonarvar

4.1.4 (2024-10-11)

Miscellaneous Chores

  • include LICENSE and LEGAL files to publish (09f366f) by @alimd

4.1.3 (2024-10-11)

Note: Version bump only for package @alwatr/fetch

4.1.2 (2024-10-10)

Dependencies update

  • bump the development-dependencies group with 10 updates (fa4aaf0) by @dependabot[bot]

4.1.1 (2024-10-08)

Note: Version bump only for package @alwatr/fetch

4.1.0 (2024-09-29)

Features

  • use package-tracer (cc3c5f9) by @mohammadhonarvar

Bug Fixes

  • all dependeny topology (1c17f34) by @mohammadhonarvar
  • fetch: remove unused import from fetch core module (28ec726) by @alimd

Code Refactoring

  • fetch: update fetch package to use @alwatr/parse-duration for timeout and retryDelay durations (1108c54) by @alimd
  • fetch: Update logger import and initialization (1f0451c) by @alimd
  • fetch: use new DictionaryReq type (a8149cf) by @alimd
  • update Dictionary type definitions (c94cbc4) by @alimd
  • use new type-helper global types and remove all import types (08b5d08) by @alimd
  • wait: rename package to delay (cf8c45c) by @alimd

Miscellaneous Chores

  • fetch: change the license to AGPL-3.0 (edf9069) by @ArmanAsadian
  • Update build and lint scripts (392d0b7) by @alimd

Dependencies update

  • bump @types/node (3d80fed) by @dependabot[bot]

4.0.1 (2024-09-21)

Note: Version bump only for package @alwatr/fetch

4.0.0 (2024-09-15)

⚠ BREAKING CHANGES

  • fetch: queryParametters renamed to queryParams

Code Refactoring

  • fetch: handle fetchJson error responses properly (ae8fe24) by @alimd
  • fetch: update query parameters handling (939b3d5) by @alimd

Dependencies update

  • bump the development-dependencies group across 1 directory with 10 updates (9ed98ff) by @dependabot[bot]
  • update (c36ed50) by @alimd

3.1.8 (2024-08-31)

Miscellaneous Chores

3.1.7 (2024-08-31)

Note: Version bump only for package @alwatr/fetch

3.1.6 (2024-08-31)

Dependencies update

  • update all dependencies (1e0c30e) by @alimd

3.1.5 (2024-07-04)

Dependencies update

  • update all dependencies (0e908b4) by @

3.1.4 (2024-05-12)

Dependencies update

3.1.3 (2024-04-25)

Note: Version bump only for package @alwatr/fetch

3.1.2 (2024-03-28)

Note: Version bump only for package @alwatr/fetch

3.1.1 (2024-01-31)

Bug Fixes

  • exported types by add .js extensions to all imports (fc3d83e) by @alimd

Miscellaneous Chores

3.1.0 (2024-01-24)

Features

  • fetch: fetch json (b089f12) by @njfamirm

Bug Fixes

  • fetch: better error handling on handleRetryPattern_ when user is offline (b867f30) by @alimd

Code Refactoring

  • fetch: separate core files (c7e6b09) by @njfamirm

3.0.0 (2024-01-20)

⚠ BREAKING CHANGES

  • fetch: remove serviceRequest

Co-authored-by: Ali Mihandoost ali@mihandoost.com

Features

  • fetch: alwatrAuth (28e365c) by @alimd
  • fetch: move from last repo (4b86bb5) by @njfamirm
  • fetch: Update fetch type definitions with document (38398cc) by @alimd

Code Refactoring

  • fetch: review and update everything (61ec38b) by @alimd