Orientation Arc
Routing Algorithms
Rendering and JSX
Runtime Adapters
Middleware Ecosystem
Developer Helpers
System Utilities
The following files were used as context for generating this wiki page:
The Hono RPC Client is a type-safe interface generator that enables seamless communication between a frontend or client-side application and a Hono server. By leveraging TypeScript's inference capabilities, it maps the server's routing structure to a proxy object, effectively allowing developers to call server-side routes as if they were local functions.
The core philosophy of the RPC client is to eliminate the need for manual endpoint synchronization. Instead of writing fetch calls with string-based URLs, developers use the proxy interface generated by hc (Hono Client). This ensures that request parameters, body types, and response formats are strictly typed, reducing runtime errors and improving developer ergonomics.
Architecturally, the RPC client uses a JavaScript Proxy to intercept property access and method calls. This allows it to dynamically construct the request path based on the chain of property accesses (e.g., client.users.posts[":id"].$get()). The client then translates these calls into standard HTTP requests, providing a consistent API surface regardless of the underlying server-side complexity.
The RPC client relies on the createProxy function to build a chainable API surface. Every time a property is accessed on the client object, createProxy is called recursively, appending the key to a path array. This continues until a method is invoked, which triggers the apply trap of the proxy.
The mechanism uses a Callback function that captures the path and the args passed during the invocation. This callback acts as the entry point for determining how to handle the request — whether it's a standard HTTP fetch, a URL calculation, or a WebSocket connection.
Sources: src/client/client.ts:15-31
When a user calls a method (e.g., $get), the callback creates an instance of ClientRequestImpl. This class is responsible for the actual network interaction. It transforms the provided args (including json, query, or form) into a standard Request object and executes the fetch request.
The request flow follows this chain:
baseUrl.replaceUrlParam substitutes placeholders like :id with actual values from the arguments.URLSearchParams and appended to the URL.args.json), the body is stringified and the Content-Type header is set to application/json.Sources: src/client/client.ts:33-130
The RPC client handles WebSocket connections via the $ws endpoint. When invoked, it translates the path into a WebSocket URL (replacing http with ws protocol). It optionally serializes query parameters into the URL search string.
The establishWebSocket helper allows for custom WebSocket implementations, defaulting to the native browser WebSocket. The client ensures that any provided path parameters are replaced before the connection is established.
Sources: src/client/client.ts:187-212
The ClientRequestOptions type provides granular control over how the RPC client communicates with the server. It allows users to define custom fetch functions (useful for testing or proxying) and headers that are added to every request.
Sources: src/client/types.ts:32-65
Note
When providing custom init options, exercise caution: these take the highest priority and can overwrite critical Hono-managed properties like method, body, or headers.
The following example demonstrates how to initialize the RPC client and use it to call an API endpoint.
import { hc } from 'hono/client'
import type { AppType } from './server' // Imported from the server
const client = hc<AppType>('https://api.example.com')
// Calling an endpoint: GET /users/:id
const res = await client.users[':id'].$get({
param: { id: '123' },
query: { details: 'true' }
})
if (res.ok) {
const data = await res.json()
console.log(data)
}Sources: src/client/client.ts:133-224
Sources: src/client/client.ts