Configuration
Configuration is merged from client defaults and per-call options via mergeConfig (see merge rules below).
OpenFetchConfig (request)
URL and query
url— Absolute or relative (withbaseURL).baseURL— Prepended to non-absolute paths (see URL helpers in the package:buildURL,combineURLs,isAbsoluteURL).params— Plain object serialized to a query string (default serializer; override withparamsSerializer).paramsSerializer—(params: Record<string, unknown>) => string. When set, it replaces the built-in serialization for that request (merged config). Use for repeated keys, bracket notation, or custom encoding.
Method and body
method— HTTP method; helpers set this automatically.data— Logical payload: aftertransformRequesthooks, objects (exceptFormData,URLSearchParams,Blob,ArrayBuffer, typed arrays) are JSON-stringified;content-typedefaults toapplication/jsonif missing.body— Rawfetchbody when you do not usedatathe same way; dispatch usesdataif defined, elsebody.
Headers and auth
headers—Record<string, string>(normalized to lowercase keys internally for the outgoing request).auth—{ username, password }→Authorization: Basic ….withCredentials: true— Setscredentials: 'include'unlesscredentialsis set explicitly.
Timeouts and cancellation
timeout— Milliseconds; uses an internalAbortControllermerged withsignalviamergeAbortSignals.signal— ExternalAbortSignal; combined with timeout abort.
Response handling
responseType—"json"|"text"|"arraybuffer"|"blob"|"stream".
If omitted, dispatch infers JSON fromContent-Type: application/json, otherwise reads as text.rawResponse— Whentrue,dispatchreturns anOpenFetchResponsewhosedatais the nativeResponsewith an unread body. Body parsing and thetransformResponsechain are skipped. Request interceptors still ran earlier; response interceptors still run and seedataas thatResponse. Middleware that expects parsed JSON inctx.response.datawill not see transforms until you callresponse.json()/text()yourself. Pair withcloneResponse(package export) if you need two independent reads of the sameResponse.validateStatus—(status: number) => boolean. Default: 200–299 inclusive. If false, throwsOpenFetchErrorwith codeERR_BAD_RESPONSEand attaches the response.
Transforms
transformRequest— Array of(data, headers) => unknown. Run in order before building the fetch body.transformResponse— Array of(data) => T. Run on successful responses after parsing.
Middleware, retry, cache hints
middlewares— Array of middleware functions (concatenated with defaults).retry— Shallow-merged retry options forcreateRetryMiddleware(defaults + per request).memoryCache— Per-request overrides for cache middleware:ttlMs,staleWhileRevalidateMs,skip.
Ergonomics
unwrapResponse— Whentrue,get/post/… returndataonly instead of fullOpenFetchResponse. Useful for RSC and minimal call sites.
RequestInit passthrough
These RequestInit fields are typed on OpenFetchConfig and passed to fetch:
cache, credentials, integrity, keepalive, mode, redirect, referrer, referrerPolicy.
OpenFetchResponse
ts
type OpenFetchResponse<T = unknown> = {
data: T;
status: number;
statusText: string;
headers: Record<string, string>;
config: OpenFetchConfig;
};Other exports (main package)
Useful when building tooling, logs, or custom middleware:
| Export | Role |
|---|---|
assertSafeHttpUrl(url) | Optional guard for untrusted URLs (see Errors & security). |
maskHeaderValues(headers, options?) | Redact sensitive header values (partial / hash strategies). |
cloneResponse(res) | Clone a native Response so the body can be read more than once. |
generateIdempotencyKey, hasIdempotencyKeyHeader, ensureIdempotencyKeyHeader | Helpers for POST retry idempotency (see Retry & cache). |
InterceptorManager | Low-level stack; normally you use client.interceptors. |
| Types | OpenFetchConfig, OpenFetchResponse, Middleware, OpenFetchContext, … |
Plugins and fluent client live under @hamdymohamedak/openfetch/plugins and /sugar — see Plugins & fluent API.
Merge behavior (mergeConfig)
- Top-level keys: later config wins.
headers: shallow merge; per-call headers override defaults.middlewares,transformRequest,transformResponse: concatenated (defaults first, then call-specific).retry,memoryCache: shallow merge of objects.- Prototype-pollution keys (
__proto__,constructor,prototype) are stripped from merged objects and nestedheaders/retry/memoryCache.
Quick checklist (common options)
| Goal | Config / approach |
|---|---|
| JSON API base URL | baseURL + relative url; get/post helpers |
| Query string | params or custom paramsSerializer |
| Bearer token | headers: { authorization: "Bearer …" } |
| Timeout | timeout (ms) or timeout(ms) plugin |
| Cancel | signal from AbortController |
| Only body value | unwrapResponse: true |
| Binary / file | responseType: "blob" or "arraybuffer" |
| Streaming | responseType: "stream" |
Raw fetch Response | rawResponse: true or fluent .raw() |
| Retries | createRetryMiddleware or retry() plugin |
| GET caching | createCacheMiddleware + MemoryCacheStore |
