new KizunaClient()
Build a fully typed HTTP client from a ts-kizuna contract using the native fetch API.
Create a fully typed HTTP client from a contract. The returned client mirrors the route structure, so each route becomes a function that accepts typed arguments and returns a typed response.
pnpm add @ts-kizuna/fetchbun add @ts-kizuna/fetchnpm install @ts-kizuna/fetchimport { KizunaClient } from '@ts-kizuna/fetch';Parameters
new KizunaClient(contract: Contract, config: ClientConfig): Client| Parameter | Type | Description |
|---|---|---|
contract | Contract | The contract from k.contract |
config | ClientConfig | Client configuration |
ClientConfig
| Option | Type | Required | Description |
|---|---|---|---|
baseUrl | string | Yes | Base URL prepended to every route path |
baseHeaders | Record<string, string> | No | Headers merged into every request |
credentials | RequestCredentials | No | Passed as credentials to every fetch call |
fetch | typeof fetch | No | Custom fetch implementation (e.g. for testing or a polyfill) |
onRequest | (context) => void | Promise<void> | No | Callback before each request, receiving { url, method, headers, route }. May be async. |
requestContext | Record<string, string> | * | Header values for the contract's request context, required when any header is |
Returns
new KizunaClient() returns the Client, mirroring the contract's route groups. Each route becomes a function accepting { params?, query?, body?, headers?, fetchOptions? } and returning a Promise resolving to { status, body, headers }.
params is typed from the route's pathParams schema output when one is declared (matching the server-side handler), otherwise from the :param placeholders in the path.
The response is a discriminated union over the route's declared status codes. Narrow on status to access the correctly typed body.
Example
When the contract secures routes with identities, send the credential in baseHeaders:
import { KizunaClient } from '@ts-kizuna/fetch';
import { contract } from './contract';
const apiClient = new KizunaClient(contract, {
baseUrl: 'http://localhost:3000',
baseHeaders: {
Authorization: `Bearer ${token}`,
},
});
const result = await apiClient.users.createUser({
body: {
name: 'Alice',
email: 'alice@example.com',
},
});
if (result.status === 201) {
console.log(result.body.id);
} else {
console.error(result.body.detail);
}Per-request options
Pass fetchOptions to customize individual requests:
const { body } = await client.users.listUsers({
query: {
page: 1,
},
fetchOptions: {
signal: AbortSignal.timeout(5000),
},
});See the Fetch client guide for per-request headers, validation errors, and response type narrowing.