Rust implementation of oRPC — type-safe RPC with first-class Tauri support.
Build fully type-safe APIs in Rust with auto-generated TypeScript types, compatible with the official @orpc/client and @orpc/tanstack-query ecosystem.
- Type-safe procedures — Builder API with compile-time middleware composition
- Wire-compatible — Matches
@orpc/clientRPC protocol (request/response, SSE subscriptions) - Rust client — Typed RPC client with
#[orpc_service]proc-macro (define once → server + client) - File uploads — Multipart
ORPCFilesupport, wire-compatible with@orpc/client - TypeScript generation — Auto-generate
Client<>types via specta, works directly with@orpc/client - Tauri IPC — Zero-HTTP transport for desktop apps, with
Channel-based subscriptions - Axum integration — RPC + OpenAPI endpoints with SSE keep-alive
- TanStack Query —
useQuery/useMutationvia@orpc/tanstack-queryout of the box
┌─────────────────────────────────────────────────┐
│ TypeScript │
│ │
│ bindings.ts ──▶ @orpc/client ──▶ @orpc/tanstack-query
│ ▲ ▲ │
│ │ TauriLink / RPCLink │
└───────┼──────────────┼──────────────────────────┘
│ │
┌─────────────────────────────┼──────────────┼──────────┐
│ Rust │ │ │
│ │ │ │
│ orpc-specta ───────────────┘ │ │
│ ▲ │ │
│ │ ┌─────┴─────┐ │
│ orpc (builder + router) │ orpc-axum │ │
│ orpc-macros (#[orpc_service]) │ orpc-tauri │ │
│ │ └─────┬─────┘ │
│ ▼ │ │
│ orpc-procedure (type-erased engine) │ │
│ │ │ │
│ └──────────── orpc-server ───────────┘ │
│ │
│ orpc-client (Rust RPC client) ◀── orpc-macros │
└───────────────────────────────────────────────────────┘
| Crate | Description |
|---|---|
orpc-procedure |
Type-erased execution engine |
orpc |
Type-safe builder API, router, middleware |
orpc-macros |
#[orpc_service] proc-macro (server + client from trait) |
orpc-client |
Rust HTTP client with SSE subscriptions |
orpc-server |
Wire protocol (RPC, SSE, OpenAPI) |
orpc-axum |
Axum HTTP integration |
orpc-specta |
TypeScript type generation |
tauri-plugin-orpc |
Tauri v2 IPC plugin |
| Package | Description |
|---|---|
@orpc-rs/tauri |
TauriLink for @orpc/client |
use orpc::*;
#[derive(Serialize, Deserialize)]
struct Planet { id: u32, name: String }
#[derive(Serialize, Deserialize)]
struct FindInput { name: String }
// Define the service trait — single source of truth
#[orpc_service(context = AppCtx)]
pub trait PlanetApi {
async fn list(&self, ctx: AppCtx) -> Result<Vec<Planet>, ORPCError>;
async fn find(&self, ctx: AppCtx, input: FindInput) -> Result<Planet, ORPCError>;
}
// Server: implement the trait
struct MyApi;
impl PlanetApi for MyApi {
async fn list(&self, ctx: AppCtx) -> Result<Vec<Planet>, ORPCError> { /* ... */ }
async fn find(&self, ctx: AppCtx, input: FindInput) -> Result<Planet, ORPCError> { /* ... */ }
}
// Build router from trait impl (auto-generated function)
let router = planet_api_router(MyApi);
let app = orpc_axum::into_router(router, |_parts| AppCtx { /* ... */ });// PlanetApiClient is auto-generated by #[orpc_service]
let client = PlanetApiClient::new("http://localhost:3000/rpc");
let planet = client.find(&FindInput { name: "Earth".into() }).await?;import { createORPCClient } from "@orpc/client"
import { RPCLink } from "@orpc/client/fetch"
const client = createORPCClient(new RPCLink({ url: "/rpc" }))
// Wire-compatible with Rust server
const planet = await client.planet.find({ name: "Earth" })For more control (middleware, contracts, specta schemas):
let router = router! {
"planet" => {
"list" => os::<AppCtx>()
.output(specta::<Vec<Planet>>())
.handler(list_planets),
},
};
// Auto-generate TypeScript types
orpc_specta::export_ts(&router, "../src/bindings.ts")?;| Example | Description |
|---|---|
axum-react |
Web app — Axum server + React client with RPC, OpenAPI, and SSE |
tauri-app |
Desktop app — Tauri IPC + TanStack Query, zero HTTP |
MIT