メインコンテンツまでスキップ

Hono Client

Zelt generates type-safe client types (AppType) for Hono's hc client — enabling fully type-safe API calls with IDE autocomplete.

Overview

The @zeltjs/hono-client package generates AppType from your controller signatures. This type integrates with Hono's hc client to provide:

  • Full TypeScript inference for request parameters and response bodies
  • IDE autocomplete for API endpoints
  • Compile-time type checking for API calls

Installation

pnpm add @zeltjs/hono-client

Configuration (CLI Plugin)

Add honoClientPlugin to your zelt.config.ts:

export default defineConfig({
  entry: './dist/app.js',
  plugins: [
    honoClientPlugin({
      outDir: './generated',
      output: 'app-type.ts',
    }),
  ],
});

Plugin Options

OptionTypeDefaultDescription
entrystringconfig.entryPath to built app module
outDirstring'./generated'Output directory
outputstring'app-type.ts'Output filename

Generating AppType

Run zelt build to generate the type file:

pnpm zelt build

This generates <outDir>/<output> (default: generated/app-type.ts) containing the AppType.

Generated app-type.ts

// THIS FILE IS GENERATED BY @zeltjs/hono-client. DO NOT EDIT.

export type AppType = BuildAppType<[
  Route<'GET', '/hello/:name', () => { message: string }>,
  Route<'POST', '/hello', (input: { name: string }) => { id: string }>,
]>;

Using AppType

Type-Safe API Client

const client = hc<AppType>('https://api.example.com');

// Fully typed - IDE autocomplete and type checking
const response = await client.hello[':name'].$get({
  param: { name: 'world' },
});

if (response.ok) {
  const data = await response.json();
  // data is typed as { message: string }
  console.log(data.message);
}

Testing with Type-Safe Client

describe('Hello API', () => {
  const client = hc<AppType>('http://localhost', {
    fetch: (input, init) => readyApp.http.fetch(new Request(input, init)),
  });

  it('should return greeting', async () => {
    const res = await client.hello[':name'].$get({
      param: { name: 'world' },
    });

    expect(res.status).toBe(200);
    const body = await res.json();
    expect(body.message).toBe('Hello, world!');
  });
});

How It Works

  1. Metadata Extraction — Reads route metadata from your Zelt app at build time
  2. Type Generation — Generates AppType from the extracted route information
  3. Client Integration — The generated type integrates with Hono's hc client

The generated AppType maps your controller routes to Hono's route types, enabling the hc client to infer parameter and response types automatically.