---
---

# 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

```bash
pnpm add @zeltjs/hono-client
```

## Configuration (CLI Plugin)

Add `honoClientPlugin` to your `zelt.config.ts`:

```typescript
declare function defineConfig(config: {
  entry: string;
  plugins?: any[];
}): any;
declare function honoClientPlugin(options?: {
  entry?: string;
  outDir?: string;
  output?: string;
}): any;
// ---cut---
export default defineConfig({
  entry: './dist/app.js',
  plugins: [
    honoClientPlugin({
      outDir: './generated',
      output: 'app-type.ts',
    }),
  ],
});
```

### Plugin Options

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `entry` | `string` | config.entry | Path to built app module |
| `outDir` | `string` | `'./generated'` | Output directory |
| `output` | `string` | `'app-type.ts'` | Output filename |

## Generating AppType

Run `zelt build` to generate the type file:

```bash
pnpm zelt build
```

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

### Generated app-type.ts

```typescript
import type { Route, BuildAppType } from '@zeltjs/hono-client';
// ---cut---
// 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

```typescript
type AppType = {
  hello: {
    ':name': {
      $get(args: { param: { name: string } }): Promise<Response & { json(): Promise<{ message: string }> }>;
    };
  };
};
declare function hc<T>(baseUrl: string): T;
// ---cut---
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

```typescript
import { createApp, Controller, Get, pathParam, http } from '@zeltjs/core';
declare function describe(name: string, fn: () => void): void;
declare function it(name: string, fn: () => Promise<void>): void;
declare function expect(value: any): { toBe(expected: any): void };
type AppType = {
  hello: {
    ':name': {
      $get(args: { param: { name: string } }): Promise<Response & { json(): Promise<{ message: string }> }>;
    };
  };
};
declare function hc<T>(baseUrl: string, options?: { fetch: (input: RequestInfo | URL, init?: RequestInit) => Promise<Response> }): T;

@Controller('/hello')
class HelloController {
  @Get('/:name')
  greet(name = pathParam('name')) { return { message: `Hello, ${name}!` }; }
}

const app = createApp([http({ controllers: [HelloController] })]);
const readyApp = await app.createRuntime();
// ---cut---
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.
