Efficient, reliable, and type-safe—Qubit is the ultimate RPC framework for developers working with Rust services and TypeScript clients. Forget about tedious boilerplate and complex setups; Qubit streamlines every interaction, letting you focus on building robust applications. Whether you’re developing small projects or large distributed systems, Qubit ensures smooth communication, fewer errors, and faster delivery. Build smarter, ship faster, and enjoy coding again.
-
Generated Type-Safe Clients: Say goodbye to manual type definitions, Qubit automatically generates TypeScript clients based on your Rust API, ensuring a smooth development experience.
-
Subscriptions: Build real-time, data-driven applications with subscriptions, allowing for your Rust server to push data directly to connected TypeScript clients.
-
Build Modular APIs: Organise your API handlers into nested routers, ensuring simplicity and maintainability as your service grows.
-
Serde Compatibility: Leverage Serde for seamless data serialisation and deserialisation between Rust and TypeScript.
-
Built on JSONRPC 2.0: Need a non-TypeScript client? Use any JSONRPC client in any language over WebSockets or HTTP.
- Add the required dependencies
# Cargo.toml
[dependencies]
qubit = "1.0.0-beta.0"
serde = { version = "1.0", features = ["derive"] } # Required for serialisable types
futures = "0.3" # Required for streaming functionality
tokio = { version = "1.44", features = ["full"] }
axum = "0.8"
hyper = { version = "1.6", features = ["server"] }pnpm i @qubit-rs/client@latest- Setup a Qubit router, and save the generated types
#[handler(query)]
async fn hello_world() -> String {
"Hello, world!".to_string()
}
let router = Router::new()
.handler(hello_world);
router
.as_codegen()
.write_type("./bindings.ts", TypeScript::new());- Attach the Qubit router to an Axum router, and start it
// Create a service and handle
let (qubit_service, qubit_handle) = router
.as_rpc(())
.into_service();
// Nest into an Axum router
let axum_router = axum::Router::<()>::new()
.nest_service("/rpc", qubit_service);
// Start a Hyper server
axum::serve(
tokio::net::TcpListener::bind(&SocketAddr::from(([127, 0, 0, 1], 9944)))
.await
.unwrap(),
axum_router,
)
.await
.unwrap();
qubit_handle.stop().unwrap();- Make requests from the TypeScript client
// Import transport from client, and generated server type
import { build_client, http } from "@qubit-rs/client";
import type { QubitServer } from "./bindings.ts";
// Connect with the API
const api = build_client<QubitServer>(http("http://localhost:9944/rpc"));
// Call the handlers
const message = await api.hello_world.query();
console.log("received from server:", message);Checkout all the examples in the examples directory.
| Feature | Description |
|---|---|
ts-format |
Format generated TypeScript types. Note: This adds a lot of dependencies. |
ts-esm |
Ensure import statements conform with the ES Modules spec by appending .js to paths. This likely isn't needed if a bundler is in use. |
ts-serde-json |
Add TypeScript support for serde_json. |
ts-chrono |
Add TypeScript support for chrono. |
ts-bigdecimal |
Add TypeScript support for bigdecimal. |
ts-url |
Add TypeScript support for url. |
ts-uuid |
Add TypeScript support for uuid. |
ts-bson-uuid |
Add TypeScript support for bson-uuid. |
ts-bytes |
Add TypeScript support for bytes. |
ts-indexmap |
Add TypeScript support for indexmap. |
ts-ordered-float |
Add TypeScript support for ordered-float. |
ts-heapless |
Add TypeScript support for heapless. |
ts-semver |
Add TypeScript support for semver. |
ts-smol-str |
Add TypeScript support for smol_str. |
ts-tokio |
Add TypeScript support for tokio. |
The term "Qubit" refers to the fundamental unit of quantum information. Just as a qubit can exist in a superposition of states, Qubit bridges the gap between Rust and TypeScript, empowering developers to create truly exceptional applications.
-
rspc: Similar concept, however uses a bespoke solution for generating TypeScript types from Rust structs, which isn't completely compatible with all of Serde's features for serialising and deserialising structs. -
trpc: Needs no introduction, however it being restricted to TypeScript backends makes it relatively useless for Rust developers.
