Skip to content

Getting started

Installation

Package on npm: @hamdymohamedak/openfetch. Source repo: openfetch-js/OpenFetch on GitHub.

bash
npm install @hamdymohamedak/openfetch

The package is ESM-only ("type": "module"). Import from "@hamdymohamedak/openfetch".

Subpath imports (tree-shaking)

ts
import openFetch from "@hamdymohamedak/openfetch";
import { retry, timeout, debug } from "@hamdymohamedak/openfetch/plugins";
import { createFluentClient } from "@hamdymohamedak/openfetch/sugar";

The exports field in package.json lists these entrypoints so bundlers can include only what you use. See Plugins & fluent API.

Requirements

RuntimeNotes
Node.js18+ (global fetch and AbortController)
Bun / DenoStandard fetch
BrowsersModern browsers with fetch
Cloudflare Workersfetch available in worker global

No mandatory polyfills on supported environments.

Default instance

The default export is a client created with createClient() and no initial defaults:

ts
import openFetch from "@hamdymohamedak/openfetch";

const res = await openFetch.get("https://api.example.com/v1/users");
// res is OpenFetchResponse: { data, status, statusText, headers, config }

Named client with createClient / create

createClient and create are aliases. Pass initial defaults; you can still mutate client.defaults later.

ts
import { createClient } from "@hamdymohamedak/openfetch";

const api = createClient({
  baseURL: "https://api.example.com",
  headers: { Authorization: "Bearer <token>" },
  timeout: 10_000,
  unwrapResponse: true,
});

const users = await api.get("/v1/users");
// With unwrapResponse: true, users is the parsed body only (T), not OpenFetchResponse

HTTP helpers (overview)

Each method returns Promise<OpenFetchResponse<T>> unless unwrapResponse is true, then Promise<T>.

MethodNotes
request(urlOrConfig, config?)url string/URL or full config object
get, head, optionsURL + optional config
post, put, patchURL, optional data, optional config — plain objects get JSON body + content-type when no CT set
deleteURL + optional config

URL required: If the merged config has no url, the client throws: openfetch: `url` is required.

For method-by-method examples (query params, JSON, FormData, unwrapResponse), see HTTP methods.

Registering middleware

ts
import { createClient, createRetryMiddleware } from "@hamdymohamedak/openfetch";

const client = createClient({
  middlewares: [createRetryMiddleware()],
});
// or later:
client.use(createRetryMiddleware({ maxAttempts: 5 }));

See Interceptors & middleware and Retry & cache.

Plugins (shorter DX)

Same behavior as createRetryMiddleware, with an attempts alias:

ts
import { createClient } from "@hamdymohamedak/openfetch";
import { retry, timeout, hooks, debug, strictFetch } from "@hamdymohamedak/openfetch/plugins";

const client = createClient({ baseURL: "https://api.example.com" })
  .use(retry({ attempts: 3, baseDelayMs: 400 }))
  .use(timeout(12_000))
  .use(debug({ includeRequestHeaders: true, maskStrategy: "partial" }));

Register retry before timeout. Full plugin reference: Plugins & fluent API.

Next

MIT · @hamdymohamedak/openfetch