@robojs/trpc
Type-safe APIs with tRPC, fully managed for Robo.js.
Add a tRPC server and client to your Robo automatically. This plugin sets up a tRPC router with automatic registration, type-safe procedure calls, and support for both React Query hooks and standalone clients.
End-to-end type safety means your client knows exactly what the server expects and returns — no manual type definitions, no runtime surprises.
Features
End-to-end Types
Full type safety from server procedures to client calls
Auto Registration
Router captured automatically via custom initTRPC wrapper
React Query
Built-in hooks with caching, loading states, and invalidation
Standalone Client
Direct procedure calls without React dependency
Zod Validation
Schema-based input validation for every procedure
Seed Files
Working server, client, and start hook out of the box
Installation
This plugin requires @robojs/server for HTTP routing.
npx robo add @robojs/server@next @robojs/trpc@nextOr create a new project with both plugins pre-installed:
npx create-robo@next my-project -p @robojs/server@next @robojs/trpc@nextWe also recommend installing zod for input validation:
npm install zodQuick start
When you install the plugin, it seeds three files into your project:
These give you a working tRPC setup out of the box. Define procedures on the server, call them from the client — fully typed.
Define a procedure
import { initTRPC } from '@robojs/trpc/server.js'
import { z } from 'zod'
const t = initTRPC.create()
export const appRouter = t.router({
hello: t.procedure
.input(z.object({ text: z.string() }))
.query(({ input }) => {
return { message: `Hello ${input.text}` }
})
})
export type AppRouter = typeof appRouterimport { initTRPC } from '@robojs/trpc/server.js'
import { z } from 'zod'
const t = initTRPC.create()
export const appRouter = t.router({
hello: t.procedure
.input(z.object({ text: z.string() }))
.query(({ input }) => {
return { message: `Hello ${input.text}` }
})
})Import initTRPC from @robojs/trpc/server.js, not from @trpc/server. The plugin wraps tRPC's initializer to automatically register your router.
Call it from the client
Use the standalone client for direct calls:
import { trpcClient } from '../trpc/client'
const result = await trpcClient.hello.query({ text: 'World' })
console.log(result.message) // "Hello World"import { trpcClient } from '../trpc/client'
const result = await trpcClient.hello.query({ text: 'World' })
console.log(result.message) // "Hello World"Or use React Query hooks for automatic caching and loading states:
import { trpc } from '../trpc/client'
function Greeting() {
const { data, isLoading } = trpc.hello.useQuery({ text: 'World' })
if (isLoading) return <span>Loading...</span>
return <span>{data?.message}</span>
}import { trpc } from '../trpc/client'
function Greeting() {
const { data, isLoading } = trpc.hello.useQuery({ text: 'World' })
if (isLoading) return <span>Loading...</span>
return <span>{data?.message}</span>
}React Query hooks require wrapping your app in TRPCProvider. See the client guide for setup.
How it works
The plugin handles tRPC integration through three mechanisms:
-
Router registration. The custom
initTRPCfrom@robojs/trpc/server.jswraps tRPC's router method to automatically capture your router instance. No manual registration needed. -
API routing. The plugin registers a catch-all API route at
/api/trpc/*through@robojs/server. All tRPC procedure calls are handled by this endpoint. -
Start hook. A seeded
_startevent handler imports your server file at startup, triggering router registration before any requests arrive.
The result is a tRPC setup that works with zero configuration — install the plugin, define procedures, and start calling them.
