Integrations
Hono
Type-safe API client from your Hono server
The @spoosh/hono package transforms your Hono app type into Spoosh's ApiSchema format, giving you end-to-end type safety.
For proper type inference, your Hono routes must follow the Hono RPC guide. Chain your routes directly on the app instance and export the app type.
Installation
npm install @spoosh/honoSetup
Server (Hono)
Define your Hono routes and export the app type:
import { Hono } from "hono";
import { zValidator } from "@hono/zod-validator";
import { z } from "zod";
const app = new Hono()
.basePath("/api")
.get("/posts", (c) => {
return c.json([
{ id: 1, title: "Hello World" },
{ id: 2, title: "Getting Started" },
]);
})
.post("/posts", zValidator("json", z.object({ title: z.string() })), (c) => {
const body = c.req.valid("json");
return c.json({ id: 3, title: body.title });
})
.get("/posts/:id", (c) => {
const id = c.req.param("id");
return c.json({ id: Number(id), title: "Post Title" });
})
.delete("/posts/:id", (c) => {
return c.json({ success: true });
});
// Export the app type for client usage
export type AppType = typeof app;Client (Spoosh)
Use HonoToSpoosh to convert the Hono type:
import { createSpoosh } from "@spoosh/core";
import { createReactSpoosh } from "@spoosh/react";
import type { HonoToSpoosh } from "@spoosh/hono";
import type { AppType } from "./server";
type ApiSchema = HonoToSpoosh<AppType>;
const spoosh = createSpoosh<ApiSchema>({
baseUrl: "http://localhost:3000/api",
plugins: [],
});
export const { useRead, useWrite } = createReactSpoosh(spoosh);Usage
All API calls are fully typed:
// GET /api/posts
const { data: posts } = await api.posts.$get();
// posts: { id: number; title: string }[]
// POST /api/posts
const { data: newPost } = await api.posts.$post({
body: { title: "New Post" }, // body is typed
});
// newPost: { id: number; title: string }
// GET /api/posts/1
const { data: post } = await api.posts[1].$get();
// post: { id: number; title: string }
// DELETE /api/posts/1
await api.posts[1].$delete();Type Mapping
| Hono | Spoosh |
|---|---|
c.json(data) | Response data type |
zValidator("json", schema) | Request body type |
zValidator("query", schema) | Query params type |
zValidator("form", schema) | Form data type |
/posts/:id | posts._ (dynamic segment) |
Path Parameters
Dynamic segments (:id, :slug, etc.) are converted to _ in the schema:
// Hono route: /users/:userId/posts/:postId
// Spoosh path: api.users[userId].posts[postId].$get()