# Hono

Generate [Hono](https://hono.dev/) server templates with full validation from your OpenAPI specification.

## Configuration

Set the `client` option to `hono`:

```ts
import { defineConfig } from 'orval';

export default defineConfig({
  petstore: {
    input: {
      target: './petstore.yaml',
    },
    output: {
      mode: 'split',
      client: 'hono',
      target: 'src/petstore.ts',
      override: {
        hono: {
          handlers: 'src/handlers',
        },
      },
    },
  },
});
```

## Generated Files

```
src/
├── handlers/
│   ├── createPets.ts
│   ├── listPets.ts
│   ├── showPetById.ts
│   └── updatePets.ts
├── petstore.ts           # Hono app with routes
├── petstore.context.ts   # Type-safe context
├── petstore.schemas.ts   # Request/response schemas
├── petstore.validator.ts # Hono validator
└── petstore.zod.ts       # Zod schemas
```

## Handler Template

Orval generates handler templates with built-in validation:

```ts
/**
 * Generated by orval 🍺
 * Do not edit manually.
 * Swagger Petstore
 * OpenAPI spec version: 1.0.0
 */
import { createFactory } from 'hono/factory';
import { zValidator } from '../petstore.validator';
import { ListPetsContext } from '../petstore.context';
import { ListPetsQueryParams, listPetsResponse } from '../petstore.zod';

const factory = createFactory();

export const listPetsHandlers = factory.createHandlers(
  zValidator('query', ListPetsQueryParams),
  zValidator('response', listPetsResponse),
  async (c: ListPetsContext) => {
    // Implement your logic here
  },
);
```

## Implementing Handlers

Add your business logic to the generated handlers:

> Re-running orval reconciles your handler files according to
> [`override.hono.handlerGenerationStrategy`](/docs/reference/configuration/output#handlergenerationstrategy)
> (default `smart`). With `smart`, orval only updates the parts it owns — its own
> imports (names, paths, casing) and the `zValidator(...)` arguments, and appends
> handlers for new operations — while preserving your custom imports, middleware,
> handler bodies, and top-level helpers. Use `skip` to freeze a file, or `full`
> for the legacy behavior that rebuilds the wrapper and keeps only the body.

```ts
export const listPetsHandlers = factory.createHandlers(
  zValidator('query', ListPetsQueryParams),
  zValidator('response', listPetsResponse),
  async (c: ListPetsContext) => {
    return c.json([
      { id: 1, name: 'Buddy' },
      { id: 2, name: 'Max' },
    ]);
  },
);
```

## Running the Server

```bash
wrangler dev src/petstore.ts
curl http://localhost:8787/pets
# => [{"id":1,"name":"Buddy"},{"id":2,"name":"Max"}]
```

## Composite Routes (tags-split)

For larger APIs, use `tags-split` mode with composite routes:

```ts
import { defineConfig } from 'orval';

export default defineConfig({
  petstore: {
    input: {
      target: './petstore.yaml',
    },
    output: {
      mode: 'tags-split',
      client: 'hono',
      target: 'src/endpoints',
      schemas: 'src/schemas',
      override: {
        hono: {
          compositeRoute: 'src/routes.ts',
        },
      },
    },
  },
});
```

This generates a combined routes file:

```ts
import { Hono } from 'hono';
import {
  listPetsHandlers,
  createPetsHandlers,
  showPetByIdHandlers,
} from './endpoints/pets/pets.handlers';

const app = new Hono();

app.get('/pets', ...listPetsHandlers);
app.post('/pets', ...createPetsHandlers);
app.get('/pets/:petId', ...showPetByIdHandlers);

export default app;
```

## Full Examples

- [Basic Hono with Zod](https://github.com/orval-labs/orval/tree/master/samples/hono/hono-with-zod)
- [Hono with Fetch Client](https://github.com/orval-labs/orval/tree/master/samples/hono/hono-with-fetch-client)
- [Composite Routes](https://github.com/orval-labs/orval/tree/master/samples/hono/composite-routes-with-tags-split)
