Zap Studio
Type-safe, framework-agnostic TypeScript packages for HTTP calls, retries, auth, validation, logging, and webhooks — install one and make your first typed call.
Zap Studio is a set of small TypeScript packages for the code every app needs: HTTP calls, retries, permission checks, validation, logs, webhooks. Pick the one you need, install it, use it. No new runtime, no framework.
This page takes about five minutes. At the end you will have a typed HTTP call that retries on failure.
Before You Start
You need Node.js 18, Bun 1.0, Deno 1.42, a current Cloudflare Workers release, or an evergreen browser. Runtimes has the full matrix, including the four packages that ask for more.
TypeScript 5 or later is recommended — the packages work in plain JavaScript, but the types are the point.
Install Your First Package
Start with fetch. It makes an HTTP call and validates the response against a schema.
npm install @zap-studio/fetch zodyarn add @zap-studio/fetch zodpnpm add @zap-studio/fetch zodbun add @zap-studio/fetch zoddeno add jsr:@zap-studio/fetch npm:zodYou also need a schema library that implements Standard Schema — Zod, Valibot, or ArkType. This page uses Zod.
Make a Typed Call
A schema describes the shape you expect back. You pass it to api.get, which validates the response at runtime and infers the type from it.
import { api } from "@zap-studio/fetch";
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.email(),
});
// `user` is typed from UserSchema — no manual annotations, no `as` casts
const user = await api.get("https://jsonplaceholder.typicode.com/users/1", UserSchema);
console.log(user.name);
Run it. You get:
Leanne Graham
Change name: z.string() to name: z.number() and run it again. The call throws a ValidationError instead of handing you bad data. That is the whole idea: the response is checked before your code touches it.
Add a Second Package
Packages compose. Wrap the same call in a retry policy so a flaky network does not break it.
npm install @zap-studio/retryyarn add @zap-studio/retrypnpm add @zap-studio/retrybun add @zap-studio/retrydeno add jsr:@zap-studio/retryA retry policy decides how many attempts to make and how long to wait between them. exponentialBackoff doubles the delay after each failure, up to a cap.
import { api } from "@zap-studio/fetch";
import { exponentialBackoff, runRetryPolicy } from "@zap-studio/retry";
import { z } from "zod";
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.email(),
});
const policy = exponentialBackoff({
maxAttempts: 3, // total attempts, including the first
baseDelayMs: 100, // first retry waits 100 ms
maxDelayMs: 2_000, // later retries never wait longer than 2 s
});
const user = await runRetryPolicy(policy, () =>
api.get("https://jsonplaceholder.typicode.com/users/1", UserSchema),
);
console.log(user.name);
Same output, three attempts instead of one. Point the URL at https://jsonplaceholder.typicode.com/nope and watch it try three times before it throws.
Pick Your Package
| Package | What you get |
|---|---|
cache |
An in-memory cache with pluggable eviction and optional TTL |
env |
Typed, validated env vars with a server/client/shared split |
fetch |
Typed responses from any API — no manual casts |
logger |
Structured logs anywhere — console today, any backend tomorrow |
monads |
Errors as values you can’t forget to handle |
oxfmt |
One decided import/package.json order — no more per-repo debate |
oxlint |
A preset per stack, zero-config linting beyond oxlint’s defaults |
permit |
Every permission check in one auditable place |
react-hooks |
Small, focused, tree-shakeable React hooks |
retry |
Retries done right — backoff, jitter, cancellation included |
store |
State with derived values that auto-track, and built-in persist |
validation |
One validation error shape, whatever schema library you use |
webhooks |
Verified, routed webhooks without a hand-rolled signature check |
webmcp |
SSR-safe tool registration for the native WebMCP browser API |
Install only the packages you need — each one works standalone.
Where to Go Next
Composition
Stack several packages on one request: retries, caching, verified webhooks.
Installation
npm and JSR, peer dependencies, subpath imports.
Runtimes
Node, Bun, Deno, Workers and browser support, per package.
Principles
The four rules every package follows — and where Zap Studio stops.
Or go deeper on what you just built: fetch Getting Started for error handling, POST/PUT/DELETE and configured clients, retry Getting Started for jitter, cancellation and result objects instead of throws.