Chapter 15

Type-safe Clients

Share Hono route types with client code.

Type-safe Clients

Hono can share route types with client code. This is often called Hono RPC. The goal is to let the client call server routes with TypeScript help.

Export the app type

Create routes in a value that TypeScript can inspect, then export its type.

const routes = app.get('/api/chapters/:slug', (c) => {
  return c.json({
    slug: c.req.param('slug'),
  })
})

export type AppType = typeof routes

The exported type describes the route path, inputs, and response shape that Hono can infer.

Create a client

Use hc from hono/client with the app type.

import { hc } from 'hono/client'
import type { AppType } from './server'

const client = hc<AppType>('https://honobook.com')

const res = await client.api.chapters[':slug'].$get({
  param: {
    slug: '03-routing',
  },
})

const chapter = await res.json()

Now the client knows the route shape and the expected parameter names.

Validation improves types

Validated routes give the client better input types.

const routes = app.post(
  '/api/chapters',
  validator('json', (value, c) => {
    if (typeof value.title !== 'string') {
      return c.json({ error: 'Title is required' }, 400)
    }

    return { title: value.title }
  }),
  (c) => {
    const input = c.req.valid('json')
    return c.json({ title: input.title }, 201)
  }
)

Type-safe clients are most useful when a frontend and Hono API live in the same workspace or share a package. For a small server-rendered book, the idea is still worth knowing before building larger apps.