API Reference

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/fetch
bun add @ts-kizuna/fetch
npm install @ts-kizuna/fetch
import { KizunaClient } from '@ts-kizuna/fetch';

Parameters

new KizunaClient(contract: Contract, config: ClientConfig): Client
ParameterTypeDescription
contractContractThe contract from k.contract
configClientConfigClient configuration

ClientConfig

OptionTypeRequiredDescription
baseUrlstringYesBase URL prepended to every route path
baseHeadersRecord<string, string>NoHeaders merged into every request
credentialsRequestCredentialsNoPassed as credentials to every fetch call
fetchtypeof fetchNoCustom fetch implementation (e.g. for testing or a polyfill)
onRequest(context) => void | Promise<void>NoCallback before each request, receiving { url, method, headers, route }. May be async.
requestContextRecord<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.

On this page