Fetchit
⚡ Quick Reference
Package: @vielzeug/fetchit · Category: Http
Key exports: createApi, createQuery, createMutation, HttpError
When to use: Typed HTTP client with a query cache, deduplication, and mutations built on native fetch. No heavy dependencies.
@vielzeug/fetchit ships a small set of composable primitives built on native fetch: createApi, createQuery, and createMutation.
Installation
pnpm add @vielzeug/fetchitnpm install @vielzeug/fetchityarn add @vielzeug/fetchitQuick Start
import { createApi, createQuery, createMutation } from '@vielzeug/fetchit';
const api = createApi({ baseUrl: 'https://api.example.com' });
const qc = createQuery({ staleTime: 5_000 });
const user = await qc.query({
key: ['users', 42],
fn: ({ signal }) => api.get<User>('/users/{id}', { params: { id: 42 }, signal }),
});
const createUser = createMutation((input: NewUser, signal: AbortSignal) =>
api.post<User>('/users', { body: input, signal }),
);
const nextUser = await createUser.mutate({ name: 'Alice' });
qc.set(['users', nextUser.id], nextUser);
qc.invalidate(['users']);Why Fetchit?
Native fetch is excellent but low-level. Fetchit adds base URL, typed path parameters, a query cache, and structured error handling with virtually no overhead.
// Before — raw fetch
const res = await fetch(`https://api.example.com/users/${userId}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const user: User = await res.json();
// After — Fetchit
const api = createApi({ baseUrl: 'https://api.example.com' });
const user = await api.get<User>('/users/{id}', { params: { id: userId } });| Feature | Fetchit | axios | ky |
|---|---|---|---|
| Bundle size | 0.2 KB | ~26 kB | ~5 kB |
| Built on | fetch | XMLHttpRequest | fetch |
| Type-safe path params | ✅ | Manual | Manual |
| Query cache | ✅ | ❌ | ❌ |
| Standalone mutations | ✅ | ❌ | ❌ |
| Zero dependencies | ✅ | ❌ | ❌ |
Use Fetchit when you want a typed fetch-based client with lightweight caching and mutation workflows without adopting a full data framework.
Consider axios or ky when you only need request helpers and do not need built-in query caching or mutation state.
Features
- Type-safe path params —
{param}placeholders extracted and validated at compile time - HTTP client —
createApi()with base URL, global headers, timeout, interceptors, and safe deduplication api.cancelAll()— abort all in-flight requests without disposing the client- Query cache —
createQuery()for stale-aware caching, prefix invalidation, and reactive subscriptions - Conditional fetching —
enabled,initialData, andplaceholderDataon everyquery()call selecton subscribe — transform data and skip redundant re-renders when the slice is unchanged- Background revalidation —
refetchOnFocusandrefetchOnReconnecton the query client - Standalone mutations —
createMutation()with retry, observable state, and built-incancel() - Mutation lifecycle callbacks —
onSuccess,onError,onSettledon the mutation definition - Request deduplication — GET/HEAD/OPTIONS/DELETE dedupe concurrent identical calls by default
- Interceptors —
use()middleware for auth tokens, logging, and request transforms - Retry with backoff — configurable attempt count, exponential delay strategy, and
shouldRetrypredicate - Abort support — query and mutation functions both receive an
AbortSignal HttpError.headers— shorthand access to response headers without optional chaining- Disposable — both clients implement
[Symbol.dispose]forusingdeclarations - Zero dependencies — 0.2 KB gzipped
Compatibility
| Environment | Support |
|---|---|
| Browser | ✅ |
| Node.js | ✅ |
| SSR | ✅ |
| Deno | ✅ |