Spring Data Power,
Rust Precision.
The familiar repository pattern for the Rust ecosystem. Generic CRUD for sqlx and MongoDB with compile-time safety and zero boilerplate.
Seamless Integration with the Rust Ecosystem
Choose your path
Migrating from Diesel?
See how our API maps to Diesel concepts and learn to migrate your models.
Read Guide arrow_forwardScaling with MongoDB?
Discover our seamless NoSQL integration and BSON type support.
Explore NoSQL arrow_forwardNew to Rust Data?
Start with our comprehensive quickstart and build your first app in minutes.
Quickstart arrow_forwardData Access, Oxidized.
Stop writing the same basic queries over and over. Focus on your domain logic while RustData handles the persistence layer.
CRUD Repositories
Auto-generated save, find_by_id, find_all, update, delete.
Type-safe Columns
Compile-time query validation prevents runtime errors.
Joins/Relations
Ergonomic API for handling One-to-Many and Many-to-Many.
Transactions
Seamless transaction management across operations.
Soft Delete
Built-in support for logical deletion patterns. Automatically filter out deleted records without modifying your queries.
REST API Generation
Optional feature to automatically generate axum routes from your repositories.
Migrations
Integrated schema migration management natively in code.
Multi-tenancy & Caching
First-class support for tenant isolation and distributed caching layers (Redis/Memcached) built right into the repository abstractions.
Professional Performance
Zero-cost abstractions mean you get the convenience of a repository pattern without sacrificing raw database performance.
Throughput (Req/sec) - Higher is better
* Benchmarks run on AWS c6i.2xlarge against Postgres 15. Simple SELECT queries.
How it compares
Choosing the right persistence crate is crucial. Here's where rustdata fits in the 2026 Rust database ecosystem.
| Feature | rustdata | Diesel | SeaORM | sqlx | rusqlite |
|---|---|---|---|---|---|
| Category | cancel Repository facade + ORM | cancel Full ORM (typed DSL) | cancel Async ORM (ActiveRecord) | cancel SQL toolkit (not an ORM) | cancel Thin SQLite wrapper |
| Latest version | cancel v0.1.0-alpha | cancel 2.3.6 | cancel 2.0 | cancel 0.8.6 | cancel 0.38.0 |
| Backends | cancel SQL + MongoDB | cancel SQL only | cancel SQL only | cancel Postgres · MySQL · SQLite · MSSQL | cancel SQLite only |
| Repository pattern & CRUD generation | check_circle First-class | cancel Manual | remove_circle_outline Active Record | cancel Manual | cancel Manual |
| Compile-time verification | check_circle Macro-checked queries | check_circle Typed query DSL | cancel Runtime only | check_circle query! vs live schema | cancel Runtime only |
| Async by default | check_circle Yes | remove_circle_outline via diesel-async | check_circle Yes | check_circle Yes | cancel No — sync only |
| Built-in migrations | check_circle Built-in | check_circle Built-in | check_circle Built-in | cancel Third-party | cancel Third-party |
| Learning curve | check_circle Low — Spring-like | cancel Steep | check_circle Gentle — Rails/Django devs | check_circle Low if you know SQL | cancel Minimal |
* Landscape as of early 2026: Diesel 2.3.6 · SQLx 0.8.6 · SeaORM 2.0 · rusqlite 0.38.0.
Want maximum compile-time safety?
Diesel's typed DSL verifies every query against your schema — at the cost of a steeper learning curve.
Prefer writing raw SQL?
sqlx checks raw queries at compile time against a live schema — but you hand-roll repositories and relations.
Want both — without the boilerplate?
rustdata generates compile-time-checked repositories over sqlx and MongoDB, with Spring-familiar ergonomics.
Less boilerplate.
use rustdata::prelude::*;
#[derive(Entity, Debug, Clone)]
pub struct User {
pub id: Uuid,
pub email: String,
pub status: UserStatus,
}
// That's it. Generates findAll, findById, save, delete...
#[repository]
pub trait UserRepository: CrudRepository<User, Uuid> {
// Custom queries are type-checked at compile time!
async fn find_by_status(&self, status: UserStatus) -> Result<Vec<User>>;
} SELECT id, email, status
FROM users
WHERE status = $1; Compile-Time Proof
Catch errors before they reach production. Typos in queries fail at compile time.
Compiling rustdata-example v0.1.0 error[E0412]: cannot find field `sttaus` in `User` --> src/repositories.rs:12:35 | 12 | async fn find_by_sttaus(&self, sttaus: UserStatus) -> Result<Vec<User>>; | ^^^^^^ help: a field with a similar name exists: `status` | = note: rustdata macro generated query validation failed error: could not compile `rustdata-example` due to previous error
Facade Crate Architecture
rustdata is a facade crate designed to keep your dependencies clean. It elegantly re-exports everything you need from our modular ecosystem.
- rustdata-core // Traits and types
- rustdata-macros // #[derive(Entity)], #[crud]
- rustdata-migrations // Schema management
# Cargo.toml [dependencies] rustdata = { version = "0.1", features = ["postgres"] } tokio = { version = "1.0", features = ["full"] }
Declarative
Persistence
Define your entities once. Our powerful macros generate robust, efficient repository implementations at compile time.
- check_circle Automatic pagination and filtering
- check_circle Compile-time schema validation
- check_circle Asynchronous by default
// Migration // CREATE TABLE users (id UUID PRIMARY KEY, name VARCHAR(255) NOT NULL); use rustdata::prelude::*; #[derive(Entity, Debug, Clone)] pub struct User { id: Uuid, name: String, } #[crud(entity = User)] trait UserRepository {} #[tokio::main] async fn main() -> Result<()> { let db = Database::connect("postgres://...").await?; let repo = UserRepositoryImpl::new(db); let user = User { id: Uuid::new_v4(), name: "Alice".to_string(), }; repo.save(&user).await?; let found = repo.find_by_id(user.id).await?; Ok(()) }