Contract first
Write one TypeScript contract that captures routes, inputs, outputs, status codes, errors, examples, and security metadata.
Write a contract, scaffold a workspace, point the UI at the typed client, and regenerate artifacts with one command.
scaffold give you a worked example)task install && task devapps/ui/app/app.vuetask generate after contract changestask api:run) when the browser runtime stops being enoughimport type { Contract, Endpoint } from "@maxanstey-meridian/rivet-ts";
export interface UserDto {
id: string;
name: string;
email: string;
}
export interface GetUserParams {
id: string;
}
export interface UsersContract extends Contract<"UsersContract"> {
GetUser: Endpoint<{
method: "GET";
route: "/users/{id}";
params: GetUserParams;
response: UserDto;
}>;
}Scaffold the app:
pnpm exec rivet-ts scaffold-mock --entry ./contracts.ts --out ./myapp
cd ./myapp
task install
task devThen use the typed client (an openapi-fetch instance checked against the generated schema.d.ts):
import { client } from "@myapp/contracts";
const { data, error } = await client.GET("/users/{id}", {
params: { path: { id: "usr_123" } },
});scaffold-mock emits the workspace with bootstrap artifacts already in place. After contract changes, task generate re-runs the pipeline: contract entry → api.contract.json (internal IR) → openapi.json (Rivet binary) → schema.d.ts (openapi-typescript).