npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fetchnix

v1.0.1

Published

A lightweight, type-safe Fetch client for modern JavaScript and TypeScript.

Readme

Fetchnix

A lightweight, type-safe Fetch client for modern JavaScript and TypeScript.

npm version npm downloads license TypeScript Zero Dependencies

Installation • Quick Start • Features • API • Errors • Configuration • Documentation • Changelog


Contents


About

Fetchnix is a lightweight wrapper around the native Fetch API.

It keeps the familiar Fetch model while providing a small set of useful request utilities:

  • Type-safe generic responses
  • Query parameter handling
  • Automatic JSON request serialization
  • Automatic response parsing
  • Request timeouts
  • Configurable retries
  • Exponential retry backoff
  • Retry-After support
  • Request cancellation
  • Typed HTTP errors
  • Zero runtime dependencies

Fetchnix does not replace the native Fetch API. It provides a small API layer on top of it.


Features

  • Zero runtime dependencies
  • TypeScript-first
  • GET, POST, PUT, PATCH and DELETE
  • Generic response types
  • Query parameter support
  • Automatic JSON serialization
  • Automatic JSON and text response parsing
  • Configurable request timeout
  • Configurable retry behavior
  • Retryable HTTP status configuration
  • Exponential retry backoff
  • Retry jitter
  • Retry-After support
  • AbortController support
  • Detailed typed errors
  • Browser and Node.js support
  • ESM and CommonJS builds
  • Small API surface

Installation

Using npm:

npm install fetchnix

Using pnpm:

pnpm add fetchnix

Using yarn:

yarn add fetchnix

Quick Start

import { fetchnix } from "fetchnix";

interface User {
  id: number;
  name: string;
}

const user = await fetchnix.get<User>(
  "https://api.example.com/users/1"
);

console.log(user.id);
console.log(user.name);

HTTP Methods

GET

const users = await fetchnix.get<User[]>(
  "https://api.example.com/users"
);

POST

const user = await fetchnix.post<User>(
  "https://api.example.com/users",
  {
    name: "Budi"
  }
);

PUT

const user = await fetchnix.put<User>(
  "https://api.example.com/users/1",
  {
    name: "Budi Updated"
  }
);

PATCH

const user = await fetchnix.patch<User>(
  "https://api.example.com/users/1",
  {
    name: "Budi Updated"
  }
);

DELETE

await fetchnix.delete(
  "https://api.example.com/users/1"
);

Query Parameters

Query parameters can be passed through the params option.

const users = await fetchnix.get<User[]>(
  "https://api.example.com/users",
  {
    params: {
      page: 1,
      limit: 20,
      active: true
    }
  }
);

The resulting request includes:

?page=1&limit=20&active=true

Existing query parameters in the URL are preserved.


JSON Requests

Plain JavaScript objects are automatically serialized as JSON.

const user = await fetchnix.post<User>(
  "https://api.example.com/users",
  {
    name: "Budi",
    age: 17
  }
);

When no Content-Type header is provided, Fetchnix automatically adds:

Content-Type: application/json

Native request bodies are passed through without JSON serialization, including:

  • FormData
  • Blob
  • URLSearchParams
  • ArrayBuffer
  • Typed arrays
  • ReadableStream
  • Strings

Custom headers are also supported:

const user = await fetchnix.post<User>(
  "https://api.example.com/users",
  {
    name: "Budi"
  },
  {
    headers: {
      Authorization: "Bearer token"
    }
  }
);

Timeouts

Set a timeout in milliseconds:

const user = await fetchnix.get<User>(
  "https://api.example.com/users/1",
  {
    timeout: 5000
  }
);

The timeout applies independently to each request attempt.

Timeout failures can be handled using FetchnixTimeoutError:

import {
  fetchnix,
  FetchnixTimeoutError
} from "fetchnix";

try {
  await fetchnix.get<User>(
    "https://api.example.com/users/1",
    {
      timeout: 5000
    }
  );
} catch (error) {
  if (
    error instanceof FetchnixTimeoutError
  ) {
    console.log(error.timeout);
    console.log(error.url);
    console.log(error.method);
  }
}

Retries

Fetchnix supports configurable retries for temporary HTTP failures.

const data = await fetchnix.get(
  "https://api.example.com/data",
  {
    retry: 3,
    retryDelay: 1000
  }
);

The default retryable status codes are:

408
429
500
502
503
504

Custom retry status codes can be provided:

const data = await fetchnix.get(
  "https://api.example.com/data",
  {
    retry: 3,
    retryStatusCodes: [
      429,
      500,
      503
    ]
  }
);

Fetchnix uses exponential backoff with jitter between retry attempts.

The retry value represents the number of retries after the initial request.

For example:

{
  retry: 3
}

allows up to four total request attempts.


Retry-After

When a retryable HTTP response contains a Retry-After header, Fetchnix uses it when calculating the retry delay.

For example:

Retry-After: 5

A maximum retry delay can be configured:

const data = await fetchnix.get(
  "https://api.example.com/data",
  {
    retry: 5,
    maxRetryDelay: 30000
  }
);

Retry-After values expressed as seconds and HTTP dates are supported.


Abort Requests

Fetchnix supports the standard AbortController API.

const controller =
  new AbortController();

const request = fetchnix.get(
  "https://api.example.com/data",
  {
    signal: controller.signal
  }
);

controller.abort();

await request;

An externally aborted request throws FetchnixAbortError.

import {
  fetchnix,
  FetchnixAbortError
} from "fetchnix";

const controller =
  new AbortController();

try {
  await fetchnix.get(
    "https://api.example.com/data",
    {
      signal: controller.signal
    }
  );
} catch (error) {
  if (
    error instanceof FetchnixAbortError
  ) {
    console.log("Request cancelled");
  }
}

External cancellation is not retried.


Errors

Fetchnix provides dedicated error classes for HTTP, timeout, and cancellation failures.

FetchnixError

FetchnixError is thrown when the server returns a non-success HTTP status after retry handling has completed.

import {
  fetchnix,
  FetchnixError
} from "fetchnix";

try {
  await fetchnix.get(
    "https://api.example.com/users/1"
  );
} catch (error) {
  if (
    error instanceof FetchnixError
  ) {
    console.log(error.status);
    console.log(error.statusText);
    console.log(error.data);
    console.log(error.url);
    console.log(error.method);
  }
}

Available properties:

| Property | Type | |---|---| | status | number | | statusText | string | | data | unknown \| null | | response | Response | | url | string | | method | string |

FetchnixTimeoutError

import {
  FetchnixTimeoutError
} from "fetchnix";

if (
  error instanceof FetchnixTimeoutError
) {
  console.log(error.timeout);
  console.log(error.url);
  console.log(error.method);
}

Available properties:

| Property | Type | |---|---| | timeout | number | | url | string | | method | string |

FetchnixAbortError

import {
  FetchnixAbortError
} from "fetchnix";

if (
  error instanceof FetchnixAbortError
) {
  console.log(error.url);
  console.log(error.method);
}

Available properties:

| Property | Type | |---|---| | url | string | | method | string |


Configuration

Fetchnix extends the standard RequestInit options with additional request controls.

| Option | Type | Default | Description | |---|---|---:|---| | params | Record<string, ...> | undefined | Query parameters | | timeout | number | undefined | Timeout per attempt in milliseconds | | retry | number | 0 | Number of retries | | retryDelay | number | 1000 | Base retry delay | | retryStatusCodes | number[] | [408,429,500,502,503,504] | Retryable HTTP statuses | | maxRetryDelay | number | 30000 | Maximum retry delay | | signal | AbortSignal \| null | undefined | External cancellation signal | | headers | HeadersInit | undefined | Request headers |

All other standard RequestInit options can be passed directly.

Example:

const data = await fetchnix.get(
  "https://api.example.com/data",
  {
    headers: {
      Authorization: "Bearer token",
      Accept: "application/json"
    },
    credentials: "include",
    cache: "no-store"
  }
);

TypeScript

Fetchnix is written in TypeScript and provides declaration files with the package.

Generic response types can be supplied to every HTTP method.

interface Product {
  id: number;
  name: string;
  price: number;
}

const product =
  await fetchnix.get<Product>(
    "https://api.example.com/products/1"
  );

console.log(product.id);
console.log(product.name);
console.log(product.price);

For collections:

interface Product {
  id: number;
  name: string;
}

const products =
  await fetchnix.get<Product[]>(
    "https://api.example.com/products"
  );

products.forEach((product) => {
  console.log(product.name);
});

Generic types describe the expected response shape. They do not perform runtime validation.


Browser & Node.js

Fetchnix uses the native Fetch API and does not include its own HTTP implementation.

It can be used in environments that provide the required Fetch APIs, including:

  • Modern browsers
  • Node.js 18+
  • TypeScript applications
  • Frontend applications
  • Server-side applications
  • CLI tools

The package provides both ESM and CommonJS builds.


API

fetchnix.get<T>()

fetchnix.get<T>(
  url,
  options?
)

Performs a GET request.

fetchnix.post<T>()

fetchnix.post<T>(
  url,
  body?,
  options?
)

Performs a POST request.

fetchnix.put<T>()

fetchnix.put<T>(
  url,
  body?,
  options?
)

Performs a PUT request.

fetchnix.patch<T>()

fetchnix.patch<T>(
  url,
  body?,
  options?
)

Performs a PATCH request.

fetchnix.delete<T>()

fetchnix.delete<T>(
  url,
  options?
)

Performs a DELETE request.


Response Parsing

Fetchnix automatically parses responses according to the response Content-Type.

For JSON responses, the body is parsed using JSON.parse().

For non-JSON responses, the body is returned as text.

Empty responses return null.

204 No Content and 205 Reset Content responses return:

null

If a response declares JSON but contains invalid JSON, Fetchnix returns the response body as text instead of throwing a JSON parsing error.


Request Bodies

Fetchnix automatically serializes plain objects:

await fetchnix.post(
  "https://api.example.com/users",
  {
    name: "Budi",
    age: 17
  }
);

Native body types are passed directly to fetch():

const form =
  new FormData();

form.append(
  "username",
  "budi"
);

await fetchnix.post(
  "https://api.example.com/users",
  form
);

Other native body types such as Blob, URLSearchParams, ArrayBuffer, typed arrays, strings, and ReadableStream are also preserved.


Documentation

Repository:

GitHub Repository

Package:

npm Package

For the complete release history, see:

CHANGELOG.md


Changelog

See the complete changelog:

CHANGELOG.md


Development

Clone the repository:

git clone https://github.com/LivvSKy/fetchnix.git
cd fetchnix

Install development dependencies:

npm install

Run TypeScript type checking:

npm run typecheck

Build the package:

npm run build

Preview the files that will be included in the npm package:

npm pack --dry-run

The compiled package is generated in:

dist/

License

MIT