<h1 align="center">

<img src="./.github/assets/readme.png" alt="Hyper Fetch" />

</h1>

<div align="center">

Framework for fetching and realtime data exchange.

**[Documentation](https://hyperfetch.bettertyped.com/) |
[Quick Start](https://hyperfetch.bettertyped.com/docs/documentation/getting-started/quick-start) |
[Guides](https://hyperfetch.bettertyped.com/docs/guides/Basic/Setup)**

</div>

<div align="center">
  <a href="https://bettertyped.com/">
    <img src="https://custom-icon-badges.demolab.com/static/v1?label=&message=BetterTyped&color=333&logo=BT" />
  </a>
  <a href="https://github.com/BetterTyped/hyper-fetch">
    <img src="https://custom-icon-badges.demolab.com/github/stars/BetterTyped/hyper-fetch?logo=star&color=brightgreen" />
  </a>
  <a href="https://github.com/BetterTyped/hyper-fetch/blob/main/License.md">
    <img src="https://custom-icon-badges.demolab.com/github/license/BetterTyped/hyper-fetch?logo=law&color=blue" />
  </a>
  <a href="https://github.com/semantic-release/semantic-release">
    <img src="https://custom-icon-badges.demolab.com/badge/semver-commitzen-e10079?logo=semantic-release&color=9146ff" />
  </a>
  <a href="https://api.codeclimate.com/v1/badges/eade9435e75ecea0c004/test_coverage">
    <img src="https://api.codeclimate.com/v1/badges/eade9435e75ecea0c004/test_coverage" />
  </a>
  <a href="https://bestofjs.org/projects/hyper-fetch" rel="nofollow">
    <img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=BetterTyped%2Fhyper-fetch%26since=daily" style="max-width: 100%;">
  </a>
</div>

<br />

**`Hyper Fetch`** is unique fetching and realtime data-exchange framework meticulously crafted to **prioritize
simplicity and efficiency**. Its **typesafe design** and **user-friendly interface** ensure a seamless integration
experience, whether you're working on the browser or the server. Next-generation features streamlines architecture
creation, grants access to the request lifecycle, and empowers rapid development of new components and functionalities,
all while facilitating **real-time data exchange**.

---

<p align="center">
	<a href="https://github.com/sponsors/prc5?tier=platinum">
		<picture>
			<img width="830" src="https://raw.githubusercontent.com/prc5/sponsors/main/assets/Platinum.png" alt="Premium sponsor banner"/>
		</picture>
	</a>
</p>

<p align="center">
	<a href="https://github.com/sponsors/prc5?tier=Platinum">
		<picture>
			<img width="830" src="https://raw.githubusercontent.com/prc5/sponsors/main/packages/platinum/sponsorkit/sponsors.svg" alt="Premium sponsor banner"/>
		</picture>
	</a>
</p>

## Key Features

🔮 **Simple setup** - [Read more](https://hyperfetch.bettertyped.com/docs/guides/basic/setup)

🎯 **Easy cancellation** - [Read more](https://hyperfetch.bettertyped.com/docs/guides/Advanced/Cancellation)

✨ **Deduplicate similar requests** -
[Read more](https://hyperfetch.bettertyped.com/docs/guides/advanced/deduplication/)

🚀 **Queueing** - [Read more](https://hyperfetch.bettertyped.com/docs/guides/advanced/queueing)

💎 **Response Caching** - [Read more](https://hyperfetch.bettertyped.com/docs/documentation/core/cache)

🔋 **Offline First** - [Read more](https://hyperfetch.bettertyped.com/docs/guides/advanced/offline)

📡 **Built-in fetcher** - [Read more](https://hyperfetch.bettertyped.com/docs/documentation/core/adapter)

🎟 **Authentication** - [Read more](https://hyperfetch.bettertyped.com/docs/guides/basic/authentication)

🔁 **Smart Retries** - [Read more](https://hyperfetch.bettertyped.com/docs/guides/basic/retries/)

## Help me keep working on this project ❤️

- [Become a Sponsor on GitHub](https://github.com/sponsors/prc5)

## Installation

The easiest way to get the latest version of Hyper Fetch is to install it via yarn or npm.

#### [Core](https://hyperfetch.bettertyped.com/docs/documentation/core/overview)

```bash
npm install --save @hyper-fetch/core
or
yarn add @hyper-fetch/core
```

#### [Sockets](https://hyperfetch.bettertyped.com/docs/documentation/sockets/overview)

```bash
npm install --save @hyper-fetch/sockets
or
yarn add @hyper-fetch/sockets
```

#### [React](https://hyperfetch.bettertyped.com/docs/documentation/react/overview)

```bash
npm install --save @hyper-fetch/core @hyper-fetch/react
or
yarn add @hyper-fetch/core @hyper-fetch/react
```

<p align="center">
	<a href="https://github.com/sponsors/prc5?tier=Gold">
		<picture>
			<img width="830" src="https://raw.githubusercontent.com/prc5/sponsors/main/assets/Gold.png" alt="Premium sponsor banner"/>
		</picture>
	</a>
</p>

<p align="center">
	<a href="https://github.com/sponsors/prc5?tier=gold">
		<picture>
			<img width="830" src="https://raw.githubusercontent.com/prc5/sponsors/main/packages/gold/sponsorkit/sponsors.svg" alt="Premium sponsor banner"/>
		</picture>
	</a>
</p>

## Packages

<table>
  <thead>
    <tr>
      <th>Package</th>
      <th>Stats</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/core">Hyper Fetch</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/core">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/core?logoColor=fff&logo=trending-up"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/core">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/core.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/react">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/core?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/sockets" >Sockets</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/sockets">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/sockets?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/sockets">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/sockets.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/sockets">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/sockets?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/react" >React </a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/react">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/react?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/react">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/react.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/react">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/react?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/adapter-firebase" >Firebase</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/firebase">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/firebase?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/firebase">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/firebase.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/firebase">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/firebase?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/adapter-firebase-admin" >Firebase Admin</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/firebase-admin">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/firebase-admin?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/firebase-admin">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/firebase-admin.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/firebase-admin">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/firebase-admin?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/adapter-graphql" >GraphQL</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/graphql">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/graphql?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/graphql">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/graphql.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/graphql">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/graphql?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/adapter-axios" >Axios</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/axios">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/axios?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/axios">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/axios.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/axios">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/axios?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
    <tr>
      <td>
        <a href="https://github.com/BetterTyped/hyper-fetch/tree/main/packages/codegen-openapi" >Codegen Openapi</a>
      </td>
      <td>
        <a href="https://www.npmjs.com/package/@hyper-fetch/codegen-openapi">
          <img src="https://custom-icon-badges.demolab.com/npm/dm/@hyper-fetch/codegen-openapi?logoColor=fff&logo=trending-up" />
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/codegen-openapi">
          <img src="https://custom-icon-badges.demolab.com/npm/v/@hyper-fetch/codegen-openapi.svg?logo=npm"/>
        </a>
        <a href="https://www.npmjs.com/package/@hyper-fetch/codegen-openapi">
          <img src="https://custom-icon-badges.demolab.com/bundlephobia/minzip/@hyper-fetch/codegen-openapi?color=E10098&logo=package" />
        </a>
      </td>
    </tr>
  </tbody>
</table>

## Examples

#### Simple Setup

```tsx
import { Client } from "@hyper-fetch/core";

// Setup our connection to the server
export const client = new Client({ url: "http://localhost:3000" });

// Create reusable requests for later use
export const postData = client.createRequest<ResponseType, RequestType, LocalErrorType, QueryParamsType>()({
  method: "POST",
  endpoint: "/data/:accountId",
});

export const getData = client.createRequest<ResponseType, RequestType, LocalErrorType, QueryParamsType>()({
  method: "GET",
  endpoint: "/user",
});
```

#### Fetching

Executing previously prepared requests is very simple. We can do this using the send method.

```ts
const { data, error, status } = await getData.send();
```

#### Mutation request

We can attach the data to the request with methods before sending it to the server. This is helpful for building our
request and attaching data to it which can be helpful when we need to create it in a few steps from data obtained during
some process.

```ts
// Set the information to request (methods return request clone - NOT mutating the source)
const request = postData
  .setParams({ accountId: 104 }) // Set Params
  .setQueryParams({ paramOne: "test", paramTwo: "test2" })
  .setData({ name: "My new entity", description: "Some description" }) // Add payload data
  .send();
```

We can also pass them directly to the send method, which will add them to the request at once.

```ts
// OR pass dynamic data directly to '.send' method
const { data, error, status } = await postData.send({
  params: { accountId: 104 },
  data: { name: "My new entity", description: "Some description" },
  queryParams: { paramOne: "test", paramTwo: "test2" },
});
```

<p align="center">
	<a href="https://github.com/sponsors/prc5?tier=Silver">
		<picture>
			<img width="830" src="https://raw.githubusercontent.com/prc5/sponsors/main/assets/Silver.png" alt="Premium sponsor banner" />
		</picture>
	</a>
</p>

<p align="center">
	<a href="https://github.com/sponsors/prc5?tier=Silver">
		<picture>
			<img width="830" src="https://raw.githubusercontent.com/prc5/sponsors/main/packages/silver/sponsorkit/sponsors.svg" alt="Premium sponsor banner" />
		</picture>
	</a>
</p>

### React

#### Fetch with lifecycle

<details>
    <summary>Show me example</summary>

```tsx
import { useFetch } from "@hyper-fetch/react";

// Lifecycle fetching
const { data, error, loading, onSuccess, onError } = useFetch(getData);

onSuccess((data) => {
  console.log(data);
});

onError((error) => {
  console.log(error);
});
```

</details>

#### Manually trigger requests

<details>
    <summary>Show me example</summary>

```tsx
import { useSubmit } from "@hyper-fetch/react";

const { submit, data, error, submitting, onSubmitSuccess, onSubmitError } = useSubmit(request);

onSuccess((data) => {
  console.log(data);
});

onError((error) => {
  console.log(error);
});

return <button onClick={() => submit()}>Trigger request!</button>;
```

</details>

#### Pass dynamic data to submit method

<details>
    <summary>Show me example</summary>

```tsx
import { useSubmit } from "@hyper-fetch/react";

const { submit, data, error, submitting, onSubmitSuccess, onSubmitError } = useSubmit(request);

onSuccess((data) => {
  console.log(data);
});

onError((error) => {
  console.log(error);
});

return (
  <button
    onClick={() =>
      submit({
        params: { accountId: 104 },
        data: { name: "My new entity", description: "Some description" },
        queryParams: { paramOne: "test", paramTwo: "test2" },
      })
    }
  >
    Trigger request!
  </button>
);
```

</details>

#### Use submit promise response

<details>
    <summary>Show me example</summary>

```tsx
import { useSubmit } from "@hyper-fetch/react";

// Manual triggering
const { submit, data, error, submitting, onSubmitSuccess, onSubmitError } = useSubmit(request);

onSuccess((data) => {
  console.log(data);
});

onError((error) => {
  console.log(error);
});

const handleSubmit = (values: ValuesType, { setSubmitting }: FormikHelpers) => {
  const { data, error, status } = await submit(); // Submit method returns data!
  setSubmitting(false);
  if (data) {
    notification.success("Done!", data);
  } else {
    notification.success("Error!", error);
  }
};

return <Form onSubmit={handleSubmit}>...</Form>;
```

</details>

# [Find out more examples](https://hyperfetch.bettertyped.com/docs/guides/basic/setup)

## 💖 Our sponsors

<p align="center">
	<a href="https://github.com/sponsors/prc5">
		<img src="https://raw.githubusercontent.com/prc5/sponsors/main/packages/other/sponsorkit/sponsors.svg?raw=true" alt="My Sponsors" />
	</a>
</p>
