Tired of wrestling with RPC boilerplate? Qubit simplifies communication between your Rust services and TypeScript clients, offering a type-safe and feature-rich development experience, so you can focus on building amazing applications.
Features:
-
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.
-
Proven Base: Built on established libraries like
ts-rsfor type generation andjsonrpseeas the JSONRPC implementation.
Getting Started
- Add the required dependencies
# Cargo.toml
[]
= "1.0.0-beta.0"
= { = "1.0", = ["derive"] } # Required for serialisable types
= "0.3" # Required for streaming functionality
= { = "1.44", = ["full"] }
= "0.8"
= { = "1.6", = ["server"] }
- Setup a Qubit router, and save the generated types
async
let router = new
.handler;
router
.as_codegen
.write_type;
- Attach the Qubit router to an Axum router, and start it
// Create a service and handle
let = router
.as_rpc
.into_service;
// Nest into an Axum router
let axum_router = new
.nest_service;
// Start a Hyper server
serve
.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);
Examples
Checkout all the examples in the examples directory.
Cargo Features
| 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. |
FAQs
Qubit?
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.
Prior Art
-
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.