hyper-fetch generates typed methods from OpenAPI, and packages core apart from react
⚡ Fetching and realtime data exchange framework.
At a glance
- What is it?
- Hyper Fetch is a TypeScript API layer that gives REST, GraphQL, Firebase, WebSockets and SSE one interface, with a CLI that generates typed methods from an OpenAPI schema. It ships as separate npm packages so you can take core without React, and the repository root is an Nx workspace rather than the library itself.
- Who is it for?
- hyper-fetch fits a TypeScript team whose application talks to several backend styles and is tired of maintaining a client per protocol, since the value is the single interface plus the generated types rather than any one transport. Do not adopt it for a single REST endpoint, where `fetch` with a type assertion is less code and one fewer dependency.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The manual path and the generated path look nothing alike
The quick start shows two routes, and the difference between them is the main design question.
The manual route creates a client and then a typed request:
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();The generic parameter declares the response shape, `send()` returns a tuple of data, error and status, and the endpoint and method are plain configuration rather than a method name per route.
The generated route is a CLI command:
npx @hyper-fetch/cli generate --url https://api.example.com/openapi.jsonand the result is an SDK whose methods come from the schema:
import { sdk } from "./generated";
// Every endpoint from your schema is available as a typed method
const { data } = await sdk.users.list.send();The generated form is nicer to read, since `sdk.users.list` names the operation rather than repeating a path string. The cost is that it exists only if your backend publishes an OpenAPI document, and it means regenerating when the schema changes rather than editing a file.
Note that both paths end at the same `send()`, which is what makes the transport layer swappable without changing call sites.
One interface across five backend styles
The positioning sentence is that it is the type-safe API layer for TypeScript apps, connecting to REST, GraphQL, Firebase, WebSockets and SSE all with one consistent interface. The topic list on the repository backs that up, naming ajax, builder, cache, data-exchange, fetch, firebase, graphql, nextjs, offline, persistence, query, react, sockets, sse, swr, websockets and xhr.
The argument the README makes for that breadth is a learning-cost one: stop learning a new library for each API. That is the real reason to reach for this rather than a bundle of small libraries, and it is most convincing when a team has a GraphQL endpoint, a REST API and a WebSocket feed.
The second reason is data management, listed as built in rather than optional: caching, queuing, offline support, retries and deduplication. Those are the features that usually end up as hand-written code around whichever fetch library you chose, and the ones most likely to be subtly wrong.
The third is environment coverage: React, Next.js, Remix, Astro, Node.js and Bun, all with the same API.
The type-safety claim is specific. End-to-end TypeScript types from schema to response, full autocompletion and zero `any`. Whether that holds depends on where your types originate, which is the manual-versus-generated distinction again. In the manual route the response type is asserted by you, so the type safety is only as good as the declaration. In the generated route it comes from the schema, so a server-side change to a field type surfaces in your editor.
Four npm packages, and core is the one you probably want
The packages table lists version, downloads and minified size per package, which is a clear signal that the library is designed for consumption in pieces.
`@hyper-fetch/core` is the framework-independent layer and the one the quick start imports. `@hyper-fetch/react` is the React integration. `@hyper-fetch/sockets` is the WebSocket side. `@hyper-fetch/cli` is the generator.
That split is the adoption decision. If you are writing in React you take two packages; if you are in Node or a non-React framework you take core and sockets and nothing else. The size badges exist precisely to make that argument, since a data layer you cannot tree-shake is a liability in a frontend bundle.
The npm badges in the README point at the core package for both version and downloads, which tells you core is the package whose health you should watch, and if core moves to a major the others follow.
The repository root makes the structure explicit. `packages/` holds the published packages and `examples/` holds four example applications: a Next.js App Router project, a Next.js app, a React app and a shop. That is a broad sample, and the shop example in particular is the one to read if you want to see the data layer used for something with real state.
There is also a sibling project. The README notes that Hyper Fetch is the data layer inside Hype Stack, a full-stack template from the same author, which is worth knowing because it means the library's API decisions are shaped by one particular template's needs.
The root package.json is a workspace, not the library
Reading `package.json` at the repository root tells you how the project is developed, and it is worth understanding before you try to build anything.
The manifest is private with version `0.0.0`, which is the standard marker for a workspace root rather than a published package. Its dependencies are Nx packages at 22.6.5, covering js, next, react, vite, web and workspace, plus the `nx` CLI itself. So the build system is Nx, not a single-package build.
The scripts are all Nx invocations. Building runs `nx run-many` across `packages/*` with parallelism of 2 and `--skip-nx-cache`, and every other task follows the same shape: start, lint, format, typecheck, test and release. The `--skip-nx-cache` on all of them is a deliberate choice for CI correctness over local speed.
Test excludes two projects explicitly, firebase and firebase-admin, so the Firebase adapter is not covered by the default test run. If you rely on it, that is worth knowing before you assume the suite covers your configuration.
The release script runs a `release` target across packages sequentially, and there is a `update-version` script that calls `node ./scripts/update-package-version.js`, which is how a version bump propagates across the published packages given they carry independent versions.
Around that sits conventional tooling: `commitlint.config.js` with conventional commits, `release.config.js` for semantic-release, husky via the `prepare` script, a `.snyk` file for vulnerability scanning, oxlint and oxfmt as the lint and format tools, `pnpm-workspace.yaml` and `pnpm-lock.yaml` for pnpm, an `.nvmrc` for the Node version, and a `migrations.json` plus `documentation/` for the docs site.
There is also a `.claude/` and a `.cursor/` directory, which suggests the repository ships agent configuration alongside its tooling.
Where the abstraction costs you
Three situations argue against this layer, and one is about your own codebase rather than the library.
A single REST endpoint does not need it. `fetch` with a small type helper is twenty lines and zero dependencies, and the caching, queuing and retry behaviour is something you would not use until you have a second endpoint.
A server you do not control and cannot describe does not benefit from the generated path. If there is no OpenAPI document, you are back to the manual route with types you assert yourself, which is still better than `any` but is not the end-to-end claim.
The third is the one that decides it for a lot of teams. An abstraction that covers five backend styles is necessarily the intersection of them, not the union. If your application genuinely needs an unusual GraphQL subscription behaviour or a WebSocket protocol with custom framing, you will be reaching past the abstraction, and a project where you regularly reach past the layer is a project where the layer is costing you indirection for nothing.
The comparison against a mature alternative is straightforward in intent: Hyper Fetch's case against that is protocol breadth and the typed generated client. If your needs are HTTP only, the case is not strong.
Where Hyper Fetch is genuinely hard to replace is a codebase that mixes REST, GraphQL and realtime and has grown a bespoke client layer that nobody enjoys maintaining. In that case the migration cost is real and the abstraction earns its keep.
The licence is Apache-2.0 with a `License.md` at the root. The repository is not archived, its last push was 2026-10-12, and releases v9.1.0 and v9.0.3 were both published on 2026-10-07.
Editorial conclusion
hyper-fetch fits a TypeScript team whose application talks to several backend styles and is tired of maintaining a client per protocol, since the value is the single interface plus the generated types rather than any one transport. Do not adopt it for a single REST endpoint, where `fetch` with a type assertion is less code and one fewer dependency. Verify first which package you need, because core, react, sockets and cli are separate npm artefacts with their own versions, and if your API has no OpenAPI schema the generated path does not apply and you are using the manual request builder.
Frequently asked questions
How do I generate typed requests from an OpenAPI schema with hyper-fetch?
Run `npx @hyper-fetch/cli generate --url https://api.example.com/openapi.json`. Every endpoint from the schema then becomes a typed method on a generated SDK, used as `await sdk.users.list.send()`.
Which transports does hyper-fetch support?
REST, GraphQL, Firebase, WebSockets and SSE behind one consistent interface. The packages table separates `@hyper-fetch/sockets` for the WebSocket side from `@hyper-fetch/core`, which is the framework-independent layer.
Which hyper-fetch packages should I install?
`@hyper-fetch/core` is the base layer, `@hyper-fetch/react` is the React integration, `@hyper-fetch/sockets` is the WebSocket package and `@hyper-fetch/cli` is the generator. The README publishes a minified size badge for each, which is how you check the cost of adding the React integration.
What data management features does hyper-fetch include?
Caching, queuing, offline support, retries and deduplication, all described in the README as built in rather than added separately. In the browser this is the part that replaces the hand-written layer around a fetch call.
How is the hyper-fetch repository built and tested?
With Nx. The root package.json is private at version 0.0.0 and runs `nx run-many` across `packages/*` for build, lint, format, typecheck, test and release, with `--skip-nx-cache` on each. The test run excludes the firebase and firebase-admin projects.
What license is hyper-fetch released under?
Apache-2.0, with the License.md file at the repository root. Recent releases are hyper-fetch-v9.1.0 and hyper-fetch-v9.0.3, both dated 2026-10-07.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bettertyped-hyper-fetch)Was this useful?