oRPC
Type-safe API with oRPC
Overview
The project uses oRPC for end-to-end type safety between server procedures and client consumers.
Architecture
src/rpc/
├── procedures/
│ ├── routers/ # Feature routers
│ ├── root.ts # Root router
│ └── rpc.ts # Runtime, context, middleware, procedures
├── react.tsx # Client provider + query utils
├── server.tsx # Server-side query utils + hydration
├── openapi.ts # OpenAPI document generation
└── tags.ts # OpenAPI tagsClient Usage
Use useRpcUtils() with TanStack Query:
"use client";
import { useRpcUtils } from "@/rpc/react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
export function TodoList({ organizationId }: { organizationId: string }) {
const rpc = useRpcUtils();
const queryClient = useQueryClient();
const listQuery = useQuery(
rpc.todos.list.queryOptions({
input: { organizationId },
}),
);
const toggleMutation = useMutation(
rpc.todos.toggle.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: rpc.todos.key() });
},
}),
);
return null;
}Server Usage
Use server query utils to prefetch in Server Components:
import { getServerQueryClient, rpc } from "@/rpc/server";
export default async function Page({ organizationId }: { organizationId: string }) {
await getServerQueryClient().prefetchQuery(
rpc.todos.list.queryOptions({
input: { organizationId },
}),
);
return null;
}Do not use revalidatePath for RPC cache flow. Invalidate query keys from client mutations.