Get Started
Three commands to go from zero to generated, type-safe code.
1. Install the CLI
npm install -g @xrpckit/cli
Requires Node.js >= 18. Also works with npx @xrpckit/cli,
pnpm dlx @xrpckit/cli, or bunx xrpc.
2. Initialize your project
xrpc init
The init wizard handles the entire setup for you:
- Detects your project structure — monorepo, single app, framework
- Creates a contract file with a working starter template
- Lets you pick targets — Go server, TypeScript client, Kotlin Spring Boot, Swift, and more
- Writes
xrpc.tomlso every future run is justxrpc generate - Optionally sets up the TypeScript language-service plugin for go-to-definition on generated code
3. Generate code
xrpc generate
That's it. The CLI reads your xrpc.toml, parses the contract, and writes
type-safe code into each target's output directory.
From here on, the workflow is: edit your contract → run xrpc generate → ship.
What init creates
After running init, your project will have two new things: a contract file
that defines your API, and an xrpc.toml that tells the CLI what to generate and where.
Contract file
The contract is a regular TypeScript file that serves as the single source of truth for your API.
You use xRPC's own DSL — createRouter, group, query,
and mutation — to define the structure of your API.
Zod is used for the data layer:
describing the shape and validation rules of each endpoint's input and output.
xRPC reads both to generate type-safe, validated code for every target language.
import { z } from "zod";
import { createRouter, group, query, mutation } from "xrpckit";
const user = group("user", {
getUser: query({
input: z.object({ id: z.string().uuid() }),
output: z.object({ id: z.string(), name: z.string(), email: z.string().email() })
}),
createUser: mutation({
input: z.object({ name: z.string().min(1).max(100), email: z.string().email() }),
output: z.object({ id: z.string().uuid() })
})
});
export const router = createRouter({ user });
A contract is structured as Router → Endpoint Groups → Endpoints.
Each endpoint is either a query (read) or a mutation (write),
with typed input and output schemas.
Zod constraints like .min(), .max(), .email(), and .uuid()
carry over into the generated code as runtime validation — in every language.
For the full contract API, see API Contract.
xrpc.toml
The config file maps your contract to the targets you want to generate. Each key is a target name, and the value is the output directory where generated code will be written.
# xRPC Configuration
# Run "xrpc generate" to generate type-safe code for your targets
contract = "./src/contract.ts"
go-server = "./apps/backend"
ts-client = "./apps/web"
swift-client = "./apps/ios"
With this config in place, xrpc generate is all you need — no flags, no arguments.
The generated code is self-contained with zero runtime dependencies, using each language's standard library.
For monorepos with multiple APIs, you can define separate modules. See Configuration for multi-module setups and advanced options.
Where next?
- API Contract — full guide to endpoints, queries, mutations, and Zod schemas
- Go Server — generated handlers, validation, and routing
- TypeScript Client — fetch-based client with full type inference
- Kotlin Spring Boot — controllers, DTOs, and validation annotations
- Swift Client — async URLSession client for iOS and macOS
- Configuration — single-module vs multi-module, target options