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 🙏

© 2025 – Pkg Stats / Ryan Hefner

cutefetch

v1.2.0

Published

A sleek and minimalistic HTTP client for modern web and Node.js applications, designed with simplicity and elegance in mind.

Downloads

26

Readme

What is CuteFetch ?

CuteFetch is a HTTP client, inspired by Axios, thats offers a sleek and minimalistic solution for modern web and Node.js applications

🧊 Tiny & Efficient: Only ~66.4 kB unpacked — perfect for modern apps.

Table of Content

CuteFetch - Lightweight & Customizable HTTP Client

| Feature | Description | | ----------------------------- | ---------------------------------------------------------------------------- | | 🌟 Lightweight | A very lightweight library | | ⚡ Fast & Simple | Easy to use | | 🔄 Auto Parsing | Automatically parses JSON, text, blobs | | 🎯 Customizable | Can be customized and extended as desired | | 🔥 Modern Fetch-Based | Built based on the modern Fetch API | | 🛠 Supports Extra Requests | cf.extra() instance method for complete control | | ⏳ Timeout Support | Add timeout globally or to specific instance methods | | 🔄 Transformer Properties | Allows customization of data parsing and transformation in response handling |

How to use?

npm install cutefetch  # Or yarn add cutefetch

Includes in Project

/*For ESM*/
import CuteFetch from "cutefetch";

/*For CJS*/
const CuteFetch = require("cutefetch");

Create CuteFetch instance

const cf = new CuteFetch({
  baseURL: "https://typecode-api.vercel.app",
  timeout: 12000,
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
  mode: "cors",
  cache: "force-cache",
  credentials: "include",
});

⚙️ CuteFetch Config Props

| Property | Description | Default | Optional | | ------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | :------: | | methods | Array of HTTP request methods you plan to use (GET, POST, etc.). Must be explicitly defined. | [] | ❌ | | baseURL | Base URL to prepend to all requests | nothing | ✅ | | resultProps | Key name where the final response data will be available in the result object | data | ✅ | | credentials | Sets the credentials option for all HTTP requests | same-origin | ✅ | | cache | Sets the cache behavior for requests | default | ✅ | | mode | Sets the mode for the request | cors | ✅ | | timeout | Global timeout duration (in milliseconds) for all requests unless overridden per-request | 5000 | ✅ | | headers | Object of headers to be sent with every request (default headers can be overridden). | Default browser headers are included, such as User-Agent, Accept, Accept-Encoding, etc. | ✅ |

CuteFetch instance methods (6)

  1. cf.get()
    Syntax: cf.get('/path-to-endpoint', { Request options })
  2. cf.post()
    Syntax: cf.post('/path-to-endpoint', { Request options })
  3. cf.put()
    Syntax: cf.put('/path-to-endpoint', { Request options })
  4. cf.patch()
    Syntax: cf.patch('/path-to-endpoint', { Request options })
  5. cf.delete()
    Syntax: cf.delete('/path-to-endpoint', { Request options })
  6. cf.extra()
    Syntax: cf.extra('/path-to-endpoint', { Request options })

Request options properties:


🧰 CuteFetch - Request Properties

| Property | Default | Optional | Replaceable | | ------------------------ | --------------------------------------------------------- | :------: | :------------: | | body | undefined | ✅ | ✅ | | query | undefined | ✅ | ✅ | | headers | From CuteFetch config or default | ✅ | ✅ | | timeout | From CuteFetch config or default | ✅ | ✅ | | baseURL | From CuteFetch config or undefined | ✅ | ✅ | | credentials | From CuteFetch config or default | ✅ | ✅ | | mode | From CuteFetch config or default | ✅ | ✅ | | cache | From CuteFetch config or default | ✅ | ✅ | | method | Defined by CuteFetch method used (GET, POST, etc.) | ✅ | ❌ | | transformResponse | User-defined transformer for successful responses | ✅ | not applicable | | transformErrorResponse | User-defined transformer for error responses | ✅ | not applicable | | inspect | Custom debugger/logging function (undefined by default) | ✅ | not applicable |

Example Request

Create a Basic Instance

const cf = new CuteFetch({
  baseURL: "https://typecode-api.vercel.app",
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
  timeout: 5000,
  headers: {
    "Content-Type": "application/json",
  },
});

1. GET

Example Success Response handling:

const { data, error } = await cf.get("/api/posts", {
  timeout: 8000,
});

if (data) {
  console.log(data);
} else {
  console.log(error);
}
// Console Output
{
  success: true,
  status: 200,
  message: 'All Posts here',
  data: [
    {
      userId: 1,
      id: 1,
      title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
      body: 'quia et suscipit\n' +
        'suscipit recusandae consequuntur expedita et cum\n' +
        'reprehenderit molestiae ut ut quas totam\n' +
        'nostrum rerum est autem sunt rem eveniet architecto'
    },
    {
      userId: 1,
      id: 2,
      title: 'qui est esse',
      body: 'est rerum tempore vitae\n' +
        'sequi sint nihil reprehenderit dolor beatae ea dolores neque\n' +
        'fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\n' +
        'qui aperiam non debitis possimus qui neque nisi nulla'
    },
    ...more
  ]
}

Example Failed Response handling:

const { data, error } = await cf.get("/api/postss"); // Invalid endpoint

if (data) {
  console.log(data);
} else {
  console.log(error); // Error output in the console
}
// Console Output
{
  "success": false,
  "status": 404,
  "message": "Requested data will not be found"
}

2. POST

const post = {
  title: "তবে গল্পটা যদি আরও কিছুটা দুরে যেতো",
  body: "মনে আছে? একদিন আমরা আঁকাশের তারা গুনছিলাম। তুমি বোকার মত বলেছিলে হ্যাঁ। আমি তোমাকে একটা খোঁচা দিলাম। অমনি তোমার হুঁশ ফিরলো আর বললে, ধুর দিনের বেলা কে তাঁরা গুনলো?",
  userId: 1,
};

const { data, error } = await cf.post("/api/posts", {
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(post),
});

if (data) {
  console.log(data);
} else {
  console.log(error); // No Error
}
// Console Output
{
  success: true,
  status: 201,
  message: 'Post Successfully created',
  data: {
    title: 'তবে গল্পটা যদি আরও কিছুটা দুরে যেতো',
    body: 'মনে আছে? একদিন আমরা আঁকাশের তারা গুনছিলাম। তুমি বোকার মত বলেছিলে হ্যাঁ। আমি তোমাকে একটা খোঁচা দিলাম। অমনি তোমার হুঁশ ফিরলো আর বললে, ধুর দিনের বেলা কে তাঁরা গুনলো?',
    userId: 1,
    id: 101
  }
}

3. PUT

const { data, error } = await cf.put("/api/posts/1", {
  body: JSON.stringify({
    title: "foo",
    body: "bar",
    userId: 1,
  }),
});

if (data) {
  console.log(data);
} else {
  console.log(error); // No Error
}
// Console Output
{
  success: true,
  status: 202,
  message: 'Post updated successfully',
  data: { title: 'foo', body: 'bar', userId: 1, id: 1 }
}

4. PATCH

const { data, error } = await cf.patch("/api/posts/1", {
  body: JSON.stringify({
    title: "তুমি আমায় ডেকেছিলে এক মেঘে ঢাকা দিনে।",
  }),
});

if (data) {
  console.log(data);
} else {
  console.log(error); // No Error
}
// Console Output
{
  success: true,
  status: 202,
  message: 'Post partially updated!',
  data: {
    userId: 1,
    id: 1,
    title: 'তুমি আমায় ডেকেছিলে এক মেঘে ঢাকা দিনে।',
    body: 'quia et suscipit\n' +
      'suscipit recusandae consequuntur expedita et cum\n' +
      'reprehenderit molestiae ut ut quas totam\n' +
      'nostrum rerum est autem sunt rem eveniet architecto'
  }
}

5. DELETE

const { data, error } = await cf.delete("/api/posts/5");

if (data) {
  console.log(data);
} else {
  console.log(error); // No Error
}
// Console Output
{ success: true, status: 200, message: 'Post deleted id: 5' }

EXTRA - Methods

This method can handle any HTTP Request. Additionally, it gives the Developer more control. However, the extra method returns a Promise Response, so if you use it, you will be responsible for handling the Promise Response yourself

It's worth noting that HEAD and OPTIONS requests can also be used via the extra method.

GET request with extra method:

const response = await cf.extra("/api/posts", {
  method: "GET",
  query: {
    _limit: "1",
    _start: "2",
  },
});

const { status, statusText, ok /*... and more*/ } = response;

if (!ok) {
  // Some Error handling Logic
  console.log(await response.json());
} else {
  // manipulate respone data using response method e.g. response.text(),response.json()
  console.log(await response.json());
}
// Console Output
{
  success: true,
  status: 200,
  message: 'All Posts here',
  data: [
    {
      userId: 1,
      id: 3,
      title: 'ea molestias quasi exercitationem repellat qui ipsa sit aut',
      body: 'et iusto sed quo iure\n' +
        'voluptatem occaecati omnis eligendi aut ad\n' +
        'voluptatem doloribus vel accusantium quis pariatur\n' +
        'molestiae porro eius odio et labore et velit aut'
    }
  ]
}

Similarly, other request methods can be applied through this extra method.

inspect Property in CuteFetch Request

The inspect property is an optional feature that allows you to inspect and log detailed information about a request and its components before it's sent. You can use this feature to debug, log, or track specific aspects of a request's execution. The property is an object containing two parts:

  1. name_space: The name for the specific inspection process, which helps in identifying logs or outputs related to this request.

  2. rule: This is an object where you can specify which parts of the request to inspect. It includes options to inspect various properties of the request, such as:

    • methods: Whether to inspect the HTTP methods used.
    • method: The specific HTTP method (e.g., GET, POST).
    • timeout: The timeout value for the request.
    • credentials: The credentials used in the request.
    • mode: The mode for the request (cors, no-cors, etc.).
    • cors: Whether Cross-Origin Resource Sharing (CORS) settings are enabled.
    • cache: The cache settings for the request.
    • baseURL: The base URL used for the request.
    • full_url: The complete URL formed by combining baseURL and query parameters.
    • headers: The headers set for the request.
    • query: The query parameters included in the request.
    • body: The body content of the request.
  3. callback: A function that gets called once the inspection is done. This function receives the result of the inspection, allowing you to extract and manipulate information before or after the request is made. You can use this callback to log the inspected data or perform any additional tasks.

Example

const { error, data, status, statusText } = await cf.put("/posts/1", {
  body: JSON.stringify({
    title: "It's Ababil Nefren",
    description: "A programmer whose brain is not static!",
  }),
  query: {
    param_a: "i am a",
    param_b: "i am b",
  },
  inspect: () => ({
    name_space: "post data fetch",
    rule: {
      // methods: true,
      // method: true,
      // timeout: true,
      // credentials: true,
      // mode: true,
      // cors: true,
      // cache: true,
      baseURL: true,
      full_url: true,
      // headers: true,
      query: true,
      body: true,
    },
    callback: (result) => {
      // Way 1: Logs the whole inspected object (the full result)
      console.log(result["post data fetch"]);

      // Way 2: Correct way to extract data using the extract method
      const { body, query } = result.extract();

      if (body) {
        console.log("Body content: ", JSON.parse(body)); // Log the body content (if available)
      }

      console.log("Query parameters: ", query); // Log query parameters
    },
  }),
});

How it works:

  • name_space: This helps you identify logs specific to this request.
  • rule: By setting this to true, you specify which request parts you want to inspect. In the example above, we're inspecting the baseURL, full_url, query, and body properties.
  • callback: The callback function is executed with the result of the inspection. You can then extract specific properties (e.g., body and query) and perform actions like logging them or manipulating the data.

Notes:

  • Use the inspect feature to keep track of request parameters and details for debugging or logging purposes.
  • The callback function gives you flexibility to log, process, or store any information you need from the request.

This feature is powerful for debugging or understanding how requests are made under the hood.

Transformer: transformResponse and transformErrorResponse

Overview

  • transformResponse: This is a function that allows you to modify or transform the response data before it's made available to your code. It's called only when the request succeeds.
  • transformErrorResponse: This is a function that lets you modify or transform the error response before it's made available to your code. It is called only in the case of an error (i.e., when the request fails).

Properties

transformResponse

  • Purpose: Allows you to transform the response data after the request has succeeded.
  • Arguments: The function receives the data (the successful response) as its argument.
  • Return Value: You should return the modified data from this function. The returned data will be passed to the data property in the response object.

Example:

const { data, error } = await cf.get("/some-endpoint", {#
  transformResponse: (data) => {
    // Example: Convert response data to uppercase before returning
    return data.toUpperCase();
  },
});

In this example, any data returned from /some-endpoint will be transformed to uppercase before it's made available to your code.

transformErrorResponse

  • Purpose: Allows you to transform the error response in case of a failed request.
  • Arguments: The function receives the error (the failed response) as its argument.
  • Return Value: You should return the modified error from this function. The returned error will be passed to the error property in the response object.

Example:

const { data, error } = await cf.get("/some-endpoint", {
  transformErrorResponse: (error) => {
    // Example: Add custom message to error
    return {
      ...error,
      message: "Something went wrong while fetching data",
    };
  },
});

In this example, if the request fails, the error will be transformed by adding a custom message to it before it's made available in the error property.


Full Example with Both transformResponse and transformErrorResponse:

const { error, data, status, statusText } = await cf.put("/posts/1", {
  body: JSON.stringify({
    title: "It's Ababil Nefren",
    description: "A programmer whose brain is not static!",
  }),
  query: {
    param_a: "i am a",
    param_b: "i am b",
  },
  transformResponse: (data) => {
    // Modify the response data here, e.g., logging it or altering it
    console.log("Original Data:", data);
    return {
      ...data,
      transformed: true, // Add a custom property to the response
    };
  },
  transformErrorResponse: (error) => {
    // Modify the error response here, e.g., adding custom properties
    console.log("Error Data:", error);
    return {
      ...error,
      customError: "There was an issue with your request.",
    };
  },
});

if (data) {
  log.info("Transformed Data:", data);
} else {
  log.info("Transformed Error:", error);
}

Explanation:

  1. transformResponse is used to modify the successful response data. In the example above, the original data is logged, and a new property transformed: true is added to the response.
  2. transformErrorResponse is used to modify the error response. Here, the original error is logged, and a new custom error message is added.

When to Use:

  • Use transformResponse if you need to format or modify the data before your application uses it.
  • Use transformErrorResponse to adjust error handling or add custom messages, logging, or other properties to errors.

Custom Transformers for Response and Error Handling

Overview

  • transformResponse and transformErrorResponse are not part of the global configuration. Instead, they are optional features that developers can implement as needed.
  • Developers have the flexibility to create their custom higher-order functions for transforming responses and errors at the application level.
  • By allowing developers to define their own transformers, they can tailor the response and error handling to their specific needs, without a top-level enforced configuration.

How to Implement Custom Transformers

You can create custom functions for transforming both responses and errors within your application by defining them at the request level.

1. transformResponse (Custom Response Transformer)

This function lets you manipulate the successful response data. It can be implemented at the request level to customize how the response data is processed before it reaches your application.

Example:

const { data, error } = await cf.get("/some-endpoint", {
  transformResponse: (data) => {
    // Custom transformation logic
    // Example: Log the original data and modify it
    console.log("Original Data:", data);
    return {
      ...data,
      modified: true, // Add custom properties or modifications
    };
  },
});

In this example, the developer is free to log or transform the data returned from the endpoint as needed.

2. transformErrorResponse (Custom Error Transformer)

Similarly, you can define how to handle errors when a request fails by using transformErrorResponse. This function gives you full control over the error response data.

Example:

const { data, error } = await cf.get("/some-endpoint", {
  transformErrorResponse: (error) => {
    // Custom error transformation
    // Example: Add additional info to the error
    console.log("Error Data:", error);
    return {
      ...error,
      customErrorMessage: "An error occurred, please try again later.",
    };
  },
});

In this case, if the request fails, the developer can modify the error response to include a custom message or perform additional actions like logging.


Flexibility to Create Higher-Order Transformers

Since the transformResponse and transformErrorResponse functions are not provided by default in the global config, developers can create higher-order functions to use as transformers across their application.

Example: Custom Higher-Order Function for Transformer

Here’s how you might create a custom higher-order function that wraps the transformer logic for reuse:

function createResponseTransformer(transformer) {
  return function (data) {
    // Apply additional transformations or logic if needed
    return transformer(data);
  };
}

function createErrorTransformer(errorTransformer) {
  return function (error) {
    // Apply additional error handling logic if needed
    return errorTransformer(error);
  };
}

// Usage:
const customResponseTransformer = createResponseTransformer((data) => {
  console.log("Custom Response:", data);
  return { ...data, custom: true };
});

const customErrorTransformer = createErrorTransformer((error) => {
  console.error("Custom Error:", error);
  return { ...error, errorMessage: "A custom error occurred" };
});

const { data, error } = await cf.get("/some-endpoint", {
  transformResponse: customResponseTransformer,
  transformErrorResponse: customErrorTransformer,
});

In this approach:

  • Developers define their own transformer logic.
  • Custom transformers can be easily reused in various requests.

When to Implement Custom Transformers

  • Use transformResponse when you need to modify the data received from a successful request (e.g., to format or enrich the data before it's used in your application).
  • Use transformErrorResponse to adjust error handling (e.g., to add additional context, log errors, or format error messages in a specific way).
  • Developers can implement custom logic by creating higher-order functions, allowing flexible handling of both responses and errors.

This setup gives developers full control over the transformation process, allowing them to create higher-order functions or individual transformers as needed while avoiding enforcing global configurations.

Error and Exceptions

You need to add the corresponding HTTP method in the CuteFetch Configuration for each CuteFetch instance method you intend to use.

For example: If you want to use the cf.get() method, you need to add it to the CuteFetch Configuration.

const cf = new CuteFetch({
  methods: ["GET"],
  ...others,
});

If you call the cf.get() method without adding "GET" to the methods array in the CuteFetch configuration, you will see the following error:

Similarly, you need to add all the HTTP Request methods you intend to use to the methods Array in the CuteFetch Configuration.


If you mistakenly change the HTTP Request method, you will see the following error.

For example:

const result = await cf.get("/posts", {
  method: "POST",
});

Note: It is pointless to try to modify the Request method of these five instance methods: cf.get(), cf.post(), cf.put(), cf.patch(), cf.delete().


If you use the cf.extra() method, you must include the Request Method within the options.

For example:

const response = await cf.extra("/posts", {
  method: "GET",
});

const { status, statusText, ok /*... and more*/ } = response;

if (!ok) {
  // Some Error handling Logic
} else {
  // manipulate respone data using response method e.g. response.text(),response.json()
}

If you don't do this, you will see the following error:

For example:

const response = await cf.extra("/posts", {});

Bodyless HTTP request for CuteFetch:

 GET HEAD OPTIONS DELETE

If you include a body property in the options for the mentioned Bodyless HTTP requests, you will observe the following error.

For example:

(async () => {
  try {
    const response = await cf.extra("/posts/1", {
      method: "HEAD",
      body: JSON.stringify({ name: "Ababil", age: undefined }),
    });
    if (response.ok) {
      console.log(await response.headers);
    }
  } catch (error) {
    console.log(error);
  }
})();

How to use it in plain HTML

app.js

// Import CuteFetch from unpkg (ESM)
import CuteFetch from "https://www.unpkg.com/[email protected]/dist/index.mjs";

// create CuteFetch instance
const cf = new CuteFetch({
  baseURL: "https://typecode-api.vercel.app",
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE"],
  timeout: 12000,
  headers: {
    "Content-Type": "application/json",
  },
});

// use intance method
cf.get("/api/posts", {
  query: {
    _page: "1",
    _limit: "3",
  },
})
  .then(console.log)
  .catch(console.log);

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- linkup app.js in html -->
    <script type="module" src="./app.js"></script>
  </body>
</html>

Inside browser console

License ⚖️

Feel free to use, modify, and distribute under the terms of this license. 💻

💡 Permission:

  • Commercial use allowed 💼
  • Modification allowed 🔧
  • Distribution allowed 📦

🚫 Conditions:

  • Must include this license notice in all copies or substantial portions of the software 📜.
  • Provide attribution to the original author 🙏.

This project is licensed under the MIT License 📝.