Tiny & fetch-based
A thin wrapper over the platform fetch — no axios-sized footprint. Method shortcuts (get / post / put / patch / delete / head) and a baseURL are all you need to start.
A tiny, fetch-based HTTP client for TypeScript — request & response hooks, transformers, authorization helpers and automatic error throwing. One transport, a family of typed service clients on top.
await client.get("users/2");{
"id": 2,
"name": "Peter",
"active": true
} Every method returns a Response whose data is decoded for you. Non-2xx responses throw a ClientError you can catch — or recover from inside a hook.
A small, predictable core — and everything you reach for in a real HTTP layer already wired in.
A thin wrapper over the platform fetch — no axios-sized footprint. Method shortcuts (get / post / put / patch / delete / head) and a baseURL are all you need to start.
Intercept every request, response, and error. An error hook can return a Response to recover, or new RequestOptions to retry — token refresh in a few lines.
Shape the outgoing body and headers, or normalize incoming data, with per-request or per-client transformer functions that compose in order.
Any 4xx/5xx becomes a typed ClientError carrying the request, response and status. Duck-typed guards (isClientError*) work across bundled copies.
One code path for Node.js, the browser, and worker runtimes — fetch, Headers, Blob, FormData and proxy support resolve per environment. Ships ESM + CJS.
Harbor, Loki, OAuth2, Vault and VictoriaLogs clients extend the same Client with typed, domain-oriented APIs — share one transport, drop the boilerplate.
No client builders, no interceptor registries — a function call and a few options.
npm install hapic --savehooks & recovery
hapic runs your hooks around the whole request lifecycle. An error hook is special: return a Response to swallow the failure, or fresh RequestOptions to retry — the client recurses for you. Token refresh, backoff, and fallbacks become a handful of lines.
// auth.ts
import { createClient, isClientErrorWithStatusCode } from 'hapic';
const client = createClient({ baseURL: 'https://api.example.com/' });
// Recover from a 401 by refreshing the token, then retry
client.on('responseError', async (error) => {
if (isClientErrorWithStatusCode(error, 401)) {
const token = await refreshAccessToken();
// returning RequestOptions re-runs the original request
return {
...error.request,
headers: {
...error.request.headers,
authorization: `Bearer ${token}`,
},
};
}
// anything else keeps throwing
throw error;
}); Each sibling package extends the base Client with a typed, domain-oriented API — same hooks, same auth helpers, same instance registry. Pick one, or roll your own.
Typed client for the Harbor container registry — projects, repositories, artifacts, robots and webhooks.
OAuth2 / OpenID Connect client — authorize URLs, every token grant, introspection and userinfo.
HashiCorp Vault client — key-value v1 & v2 secret engines plus mount management.
Grafana Loki client — push log streams and run LogQL instant & range queries.
VictoriaLogs client — ingest JSON-line logs and query them with LogsQL.
The foundation. Build your own typed client on the same Client, hooks and instance registry.