Skip to content

ahonn/orpc-rs

Repository files navigation

orpc-rs

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.

Features

  • Type-safe procedures — Builder API with compile-time middleware composition
  • Wire-compatible — Matches @orpc/client RPC protocol (request/response, SSE subscriptions)
  • Rust client — Typed RPC client with #[orpc_service] proc-macro (define once → server + client)
  • File uploads — Multipart ORPCFile support, 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 QueryuseQuery / useMutation via @orpc/tanstack-query out of the box

Architecture

                        ┌─────────────────────────────────────────────────┐
                        │                   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        │
  └───────────────────────────────────────────────────────┘

Crates

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

Packages

Package Description
@orpc-rs/tauri TauriLink for @orpc/client

Quick Start

Define once — Server + 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 { /* ... */ });

Rust Client — Typed, auto-generated

// PlanetApiClient is auto-generated by #[orpc_service]
let client = PlanetApiClient::new("http://localhost:3000/rpc");
let planet = client.find(&FindInput { name: "Earth".into() }).await?;

TypeScript Client — Full type safety

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" })

Builder API (alternative)

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")?;

Examples

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

License

MIT

About

Rust implementation of oRPC, type-safe RPC with first-class Tauri support.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors