upfetch
Use up-fetch when you need a reusable fetch client with request-scoped defaults, automatic request/response shaping, runtime validation, retries, and lifecycle hooks.
Mental model
up(fetchFn, getDefaultOptions?) creates the reusable client.
getDefaultOptions(input, options, ctx) runs on every request.
upfetch(input, options?, ctx?) performs one request.
- Keep
SKILL.md high-level; load the relevant file under references/ for details.
Minimum pattern
import { up } from 'up-fetch'
import { z } from 'zod'
export const upfetch = up(fetch, () => ({
baseUrl: 'https://api.example.com',
headers: {
Authorization: readToken() ? `Bearer ${readToken()}` : undefined,
},
timeout: 5000,
}))
const user = await upfetch('/users/1', {
schema: z.object({
id: z.number(),
name: z.string(),
}),
})
Workflow
- Start with client setup and dynamic defaults.
- If the request needs auth, params, body shaping, or merge semantics, read auth and request shaping.
- If the response contract matters, read validation, parsing, and errors.
- If retries, timeouts, or hook timing matter, read retries, timeouts, and lifecycle.
- If streaming or runtime quirks matter, read streaming and runtime caveats.
High-value rules
- Pass a function as the second argument to
up(), not a plain object.
- Read auth and other mutable defaults inside that function so values stay fresh.
- Use
params and body instead of hand-serializing query strings or JSON.
- Use
schema when you need runtime trust; TypeScript generics alone do not validate payloads.
- If you want error-as-value behavior, set
reject: () => false before relying on parseResponse.
- Prefer
globalThis.fetch over imported undici.fetch.
References
- Client setup and dynamic defaults
- Auth and request shaping
- Validation, parsing, and errors
- Retries, timeouts, and lifecycle
- Streaming and runtime caveats
1---2name: upfetch3description: Load this skill for any up-fetch task: `up(fetch, getDefaultOptions?)`, `upfetch(url, options?)`. Covers dynamic defaults, auth, request shaping, validation, error handling, lifecycle timing, and runtime caveats.4---56# upfetch78Use `up-fetch` when you need a reusable fetch client with request-scoped defaults, automatic request/response shaping, runtime validation, retries, and lifecycle hooks.910## Mental model1112- `up(fetchFn, getDefaultOptions?)` creates the reusable client.13- `getDefaultOptions(input, options, ctx)` runs on every request.14- `upfetch(input, options?, ctx?)` performs one request.15- Keep `SKILL.md` high-level; load the relevant file under `references/` for details.1617## Minimum pattern1819```ts20import { up } from 'up-fetch'21import { z } from 'zod'2223export const upfetch = up(fetch, () => ({24 baseUrl: 'https://api.example.com',25 headers: {26 Authorization: readToken() ? `Bearer ${readToken()}` : undefined,27 },28 timeout: 5000,29}))3031const user = await upfetch('/users/1', {32 schema: z.object({33 id: z.number(),34 name: z.string(),35 }),36})37```3839## Workflow40411. Start with [client setup and dynamic defaults](references/client-setup-and-dynamic-defaults.md).422. If the request needs auth, params, body shaping, or merge semantics, read [auth and request shaping](references/auth-and-request-shaping.md).433. If the response contract matters, read [validation, parsing, and errors](references/validation-parsing-and-errors.md).444. If retries, timeouts, or hook timing matter, read [retries, timeouts, and lifecycle](references/retries-timeouts-and-lifecycle.md).455. If streaming or runtime quirks matter, read [streaming and runtime caveats](references/streaming-and-runtime-caveats.md).4647## High-value rules4849- Pass a function as the second argument to `up()`, not a plain object.50- Read auth and other mutable defaults inside that function so values stay fresh.51- Use `params` and `body` instead of hand-serializing query strings or JSON.52- Use `schema` when you need runtime trust; TypeScript generics alone do not validate payloads.53- If you want error-as-value behavior, set `reject: () => false` before relying on `parseResponse`.54- Prefer `globalThis.fetch` over imported `undici.fetch`.5556## References5758- [Client setup and dynamic defaults](references/client-setup-and-dynamic-defaults.md)59- [Auth and request shaping](references/auth-and-request-shaping.md)60- [Validation, parsing, and errors](references/validation-parsing-and-errors.md)61- [Retries, timeouts, and lifecycle](references/retries-timeouts-and-lifecycle.md)62- [Streaming and runtime caveats](references/streaming-and-runtime-caveats.md)