One SDK. Any API. Fully typed.
The type-safe API layer for TypeScript apps. Connect to REST, GraphQL, Firebase, WebSockets, SSE — all with one consistent interface and the best type safety in the ecosystem.
import { createClient } from "@hyper-fetch/core";
// Create a client — this is the single entry point for all your API calls
const client = createClient({ url: "https://api.example.com" });
// Define a typed request — response shape is inferred everywhere from here
const getUsers = client.createRequest<{ response: { id: number; name: string }[] }>()({
endpoint: "/users",
method: "GET",
});
// Send it — data, error, and status are fully typed
const { data, error, status } = await getUsers.send();npx @hyper-fetch/cli generate --url https://api.example.com/openapi.jsonimport { sdk } from "./generated";
// Every endpoint from your schema is available as a typed method
const { data } = await sdk.users.list.send();- 🔮 Zero guesswork — End-to-end TypeScript types from schema to response, full autocompletion, zero
any - 📡 One interface for everything — REST, GraphQL, Firebase, WebSockets, SSE — stop learning a new library for each API
- 💾 Data management built in — Caching, queuing, offline support, retries, and deduplication out of the box
- ⚡ Works everywhere — React, Next.js, Remix, Astro, Node.js, Bun — same API, every environment
// Send and destructure — all return values are typed
const { data, error, status } = await getUsers.send();// Params go in the URL, data goes in the body — both fully typed
const { data, error, status } = await createUser.send({
params: { teamId: 1 },
data: { name: "Jane", email: "jane@example.com" },
});import { useFetch } from "@hyper-fetch/react";
const UserList = () => {
// useFetch triggers the request on mount and returns typed state
const { data, loading, error } = useFetch(getUsers);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error loading users</p>;
return <ul>{data?.map((u) => <li key={u.id}>{u.name}</li>)}</ul>;
};