Typed Client
Call backend routes, jobs, agents, and channels with generated TypeScript contracts and optional React helpers.
Use the generated client to call your backend with typed inputs, results, and application errors.
Pre-setup
Run the backend locally and complete the setup for each
capability you expose. Docker belongs to those backend providers; the typed client itself
needs no defineApp or defineEnv entry. Keep backend secrets and descriptors out of the frontend.
Choose the Vite or Next.js proxy and build setup
and use the public backend origin when pulling its contract. The steps below install the
frontend packages and connect that contract.
Install the selected frontend packages
From this guide’s application/package root, install only its selected requirements:
bun add @opentelemetry/api@1.9.1 @orpc/tanstack-query@2.0.0-beta.31 @relkit/client@0.8.2 '@tanstack/query-core@>=5.80.2' '@tanstack/react-query@>=5.80.2' 'react@>=18.0.0'Keep these owner-specific versions and the lockfile together. Runtime SDKs belong in dependencies; build/type tooling belongs in devDependencies. Installing an adapter does not supply its optional SDK peers or enable the feature’s configuration.
The displayed React/query ranges are the owner’s supported peer ranges. Preserve already compatible framework versions and commit the resolved lockfile; this is not an instruction to upgrade every frontend dependency. Install the CLI as development tooling for contract pull/check:
From this guide’s application/package root, install only its selected requirements:
bun add --dev @relkit/cli@0.8.4Keep these owner-specific versions and the lockfile together. Runtime SDKs belong in dependencies; build/type tooling belongs in devDependencies. Installing an adapter does not supply its optional SDK peers or enable the feature’s configuration.
These frontend commands do not install the backend, database integrations or native agent engine. For a framework-independent caller, use the base client installation instead of the React recipe.
Pull the public contract
From the frontend root, pull the running server’s public contract into a frontend-owned directory:
bun run relkit client pull http://127.0.0.1:3000 --out .relkit/generatedThis writes contract.ts, client.ts, client-registry.d.ts, and client-manifest.json. Include
.relkit/generated/**/*.ts in the TypeScript project that checks your frontend source, as shown
in the Frontend guide, and regenerate them when the public API
changes. The backend must be reachable while you pull; do not import backend source into a
browser bundle.
The recipe explicitly declares @opentelemetry/api, the required oRPC peer, so setup does not depend
on whether a package manager automatically installs required peers.
Install the provider
Wrap your React tree in RelkitClientProvider. This small
example calls the minimal starter’s Hello route through the
same-origin development proxy.
For a separate backend origin, set baseUrl on the provider and configure its cookie/CORS boundary.
"use client";
/** Renders the minimal backend's greeting through the pulled registry and a same-origin client provider. */
import { RelkitClientProvider, useRelkitClient, useRoute } from "@relkit/client/react";
/** Displays the typed Hello result after the provider resolves backend identity.
* @returns Loading, connection failure, request failure, or the successful greeting. */
export function Greeting() {
const { status } = useRelkitClient();
const greeting = useRoute("GET /hello", { input: { name: "RELKIT" } });
if (status === "application-updated") {
return <p role="alert">The API changed. Pull its contract and restart the frontend.</p>;
}
if (status === "error") return <p role="alert">Cannot connect to the API.</p>;
if (greeting.isError) return <p role="alert">{greeting.error.message}</p>;
if (greeting.isPending) return <p role="status">Loading greeting…</p>;
return <h1>{greeting.data.message}</h1>;
}
/** Supplies the shared query cache and identity handshake to the frontend tree.
* @returns The greeting inside a same-origin RELKIT provider. */
export default function App() {
return (
<RelkitClientProvider>
<Greeting />
</RelkitClientProvider>
);
}Enforce compatibility
The provider defaults to the same-origin backend, credentialed requests, a 30-second finite request timeout, and a 10-second stream-establishment timeout. An established healthy stream is not capped by the finite timeout. From the frontend root, check the pulled contract against the running backend before shipping:
bun run relkit client check http://127.0.0.1:3000 --out .relkit/generatedFor Next.js or Vite, configure withRelkit() or relkit()
to embed the public fingerprint at build time. Both read .relkit/generated/client-manifest.json
from the frontend root; client pull is what writes it and the declarations.
The compiled public-contract fingerprint must match the backend. A mismatch enters application-updated and blocks
new typed work until frontend and backend are coordinated; unresolved mutation or control metadata is
preserved rather than retried.
Job hooks use the same provider and identity handshake. useJobTrigger retains the accepted runId, while
useJobRun observes that run without starting a subscription during server rendering. Unknown submission
outcomes remain visible for same-key recovery instead of becoming an automatic replay queue.
Find the right client API
| Task | API | Example |
|---|---|---|
| Call without React | createClient, createWebSocketClient, createAutoClient |
Transports |
| Provide clients and inspect connection status | RelkitClientProvider, useRelkitClient |
Provider and Greeting above |
| Read a route | useRoute, useSuspenseRoute, useInfiniteRoute |
Route queries |
| Submit a change | useRouteMutation, useRouteUtils |
Mutations |
| Observe a response stream | useStream |
HTTP streaming |
| Run or observe an agent | useAgent |
Agent streaming |
| Trigger, observe, or control a job | useJobRun, useJobTrigger, useJobCancel, useJobRetry |
Job clients |
| Render on the server | createServerClient, createRelkitServerContext |
Server rendering |
| Subscribe to channels | useRealtime, useChannel |
Realtime React clients |
| Embed the public fingerprint | withRelkit, relkit |
Build integration |
useRelkitClient must run inside the provider. It exposes
the client runtime and a status of loading, ready, error, or application-updated.
The client export index lists every import path and companion type.