vercel-rpc-cli
CLI that scans Rust lambda source files annotated with #[rpc_query] /
#[rpc_mutation] and generates TypeScript type definitions and a fully typed
RPC client.
Part of the vercel-rpc project.
Installation
This installs the rpc binary.
Commands
rpc scan
Parse Rust source files and print discovered procedures, structs, and enums:
Discovered 2 procedure(s), 1 struct(s), 0 enum(s):
Query hello (String) -> String [api/hello.rs]
Query time (()) -> TimeResponse [api/time.rs]
struct TimeResponse {
timestamp: u64,
message: String,
}
Also outputs a JSON manifest for tooling consumption.
rpc generate
Generate TypeScript types and a typed client from Rust source files:
This produces two files:
rpc-types.ts — TypeScript interfaces and a Procedures type map:
export interface TimeResponse {
timestamp: number;
message: string;
}
export type Procedures = {
queries: {
hello: { input: string; output: string };
time: { input: void; output: TimeResponse };
};
mutations: {};
};
rpc-client.ts — a typed RpcClient with method overloads:
export interface RpcClient {
query(key: "time"): Promise<TimeResponse>;
query(key: "hello", input: string): Promise<string>;
}
export function createRpcClient(baseUrl: string): RpcClient;
rpc watch
Watch for .rs file changes and regenerate automatically (same flags as
generate):
vercel-rpc watch mode
api dir: api
types: src/lib/rpc-types.ts
client: src/lib/rpc-client.ts
✓ Generated 2 procedure(s), 1 struct(s) in 3ms
→ src/lib/rpc-types.ts
→ src/lib/rpc-client.ts
Watching for changes in api
Changes are debounced at 200 ms. Press Ctrl+C to stop.
Flags
| Flag | Short | Default | Description |
|---|---|---|---|
--dir |
-d |
api |
Rust source directory to scan |
--output |
-o |
src/lib/rpc-types.ts |
Output path for TypeScript types |
--client-output |
-c |
src/lib/rpc-client.ts |
Output path for TypeScript client |
--types-import |
./rpc-types |
Import path for types in the client file |
What gets scanned
The parser recognizes:
- Functions annotated with
#[rpc_query]or#[rpc_mutation]— extracted as RPC procedures with their input/output types. - Structs with
#[derive(Serialize)]— converted to TypeScript interfaces. - Enums with
#[derive(Serialize)]— converted to TypeScript union types (unit variants become string literals, tuple/struct variants become tagged objects).
Type mapping
| Rust | TypeScript |
|---|---|
String, &str, char |
string |
i8..i128, u8..u128, f32, f64 |
number |
bool |
boolean |
() |
void |
Vec<T> |
T[] |
Option<T> |
T | null |
HashMap<K, V>, BTreeMap<K, V> |
Record<K, V> |
(A, B, C) |
[A, B, C] |
Result<T, E> |
T (error handled at runtime) |
| Custom structs | interface with same fields |
| Enums (unit variants) | "A" | "B" |
| Enums (tuple variants) | { A: string } | { B: number } |
| Enums (struct variants) | { A: { x: number } } |
Generated client features
The generated rpc-client.ts includes:
RpcClientinterface with typed overloads for every procedure — full autocomplete and type checking.createRpcClient(baseUrl)factory function.RpcErrorclass withstatusanddatafields for structured error handling.rpcFetchhelper — usesGETwith?input=<JSON>for queries andPOSTwith JSON body for mutations. Unwraps theresult.dataenvelope automatically.
Related crates
vercel-rpc-macro— procedural macros (#[rpc_query],#[rpc_mutation]) that generate Vercel lambda handlers from plain async functions.
License
MIT OR Apache-2.0