Diesel: A Type-Safe ORM and Query Builder for Rust
A safe, extensible ORM and Query Builder for Rust
At a glance
- What is it?
- Diesel is a Rust ORM and query builder that eliminates database interaction boilerplate and catches query errors at compile time rather than runtime. It supports PostgreSQL, MySQL, SQLite, and MariaDB, and uses Rust's type system to enforce query correctness without sacrificing performance.
- Who is it for?
- Diesel is the right ORM for Rust projects that prioritize compile-time query verification and want to eliminate runtime database errors through the type system. The minimum Rust version is 1.88.0 (from Cargo.toml).
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 5 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Diesel Solves and Who It Is For
Diesel addresses two recurring problems in Rust database code: the boilerplate of mapping SQL rows to structs, and the class of runtime errors that occur when a query references a column or type that does not exist in the schema. The README states that Diesel gets rid of boilerplate for database interaction and eliminates runtime errors without sacrificing performance.
It is designed for Rust developers building applications that communicate with PostgreSQL, MySQL, SQLite, or MariaDB. The query builder generates SQL at compile time, which means type mismatches between Rust structs and database columns become compiler errors rather than panics at runtime. This trade-off: catching more errors earlier at the cost of a steeper initial setup, is the defining characteristic of Diesel relative to lighter-weight crates.
Supported Backends and Cargo Configuration
Diesel is added to a project by selecting a backend feature flag in `Cargo.toml`. The four supported backends are PostgreSQL, MySQL, SQLite, and MariaDB:
[dependencies]
diesel = { version = "<version>", features = ["postgres"] }For SQLite:
[dependencies]
diesel = { version = "<version>", features = ["sqlite"] }The workspace Cargo.toml in the repository specifies the minimum Rust version as 1.88.0. Native library dependencies are managed through the `libsqlite3-sys`, `pq-sys`, `mysqlclient-sys`, and `openssl-sys` crates. The `diesel_cli` crate provides a command-line tool for managing schema migrations.
The repository is organized as a Cargo workspace with multiple members: `diesel/`, `diesel_cli/`, `diesel_derives/`, `diesel_migrations/`, `diesel_dynamic_schema/`, `diesel_table_macro_syntax/`, `dsl_auto_type/`, `diesel_bench/`, and example crates under `examples/postgres/`, `examples/mysql/`, and `examples/sqlite/`.
Query Builder: From Simple Loads to Complex Joins
Diesel's query builder uses Rust types to represent SQL expressions. A simple load of all rows from a table reads:
users::table.load(&mut connection)The generated SQL is `SELECT * FROM users;`. Loading all posts for a specific user:
Post::belonging_to(user).load(&mut connection)Generates `SELECT * FROM posts WHERE user_id = 1;`.
For complex queries involving subqueries, filters, and ordering, the builder composes operations as Rust method chains:
let versions = Version::belonging_to(krate)
.select(id)
.order(num.desc())
.limit(5);
let downloads = version_downloads
.filter(date.gt(now - 90.days()))
.filter(version_id.eq_any(versions))
.order(date)
.load::<Download>(&mut conn)?;This produces a correlated subquery in SQL, with Diesel handling the translation. The type system enforces that `date` is a comparable type, that `version_id` is the correct column, and that the subquery returns values of the type `version_id` expects.
Codegen Macros and Reduced Boilerplate
Diesel's derive macros reduce the boilerplate of mapping database rows to Rust structs. The `#[derive(Queryable, Selectable)]` attributes on a struct generate the `FromSql` implementations that Diesel needs to construct the struct from a query result:
#[derive(Queryable, Selectable)]
#[diesel(table_name = downloads)]
pub struct Download {
id: i32,
version_id: i32,
downloads: i32,
counted: i32,
date: SystemTime,
}Without Diesel, the equivalent requires manually implementing a `from_row` function that calls `row.get("column_name")` for every field. For inserting data, `#[derive(Insertable)]` generates the SQL binding code:
#[derive(Insertable)]
#[diesel(table_name = users)]
struct NewUser<'a> {
name: &'a str,
hair_color: Option<&'a str>,
}This approach means that renaming a column in the database schema and updating the struct field causes a compile error at the call sites that reference the old field, rather than a runtime failure when the query executes.
Raw SQL Escape Hatch
Some queries are easier to express as raw SQL than as query builder method chains. Diesel provides `sql_query` for this case, combined with `#[derive(QueryableByName)]` to map results back to a Rust struct:
#[derive(QueryableByName)]
#[diesel(table_name = users)]
struct User {
id: i32,
name: String,
organization_id: i32,
}
sql_query(include_str!("complex_users_by_organization.sql"))
.bind::<Integer, _>(organization_id)
.bind::<BigInt, _>(offset)
.bind::<BigInt, _>(limit)
.load::<User>(&mut conn)?;The README note on `include_str!` is pragmatic: keeping complex SQL in a separate file allows editors to provide SQL-specific syntax highlighting, while Diesel still handles parameter binding and result deserialization.
The `diesel_dynamic_schema` crate in the workspace provides support for queries where the schema is not known at compile time, which the standard type-safe approach cannot handle.
Limitations: Synchronous Design and Migration Coupling
Diesel is synchronous by default. The README and the getting started guide at diesel.rs document a synchronous connection model. Teams building async Rust applications (using tokio or async-std) need to either run Diesel queries on a blocking thread pool or evaluate `diesel-async`, a separate crate not in this repository. The synchronous model is a deliberate design choice, not an oversight: it simplifies the connection pool semantics and avoids the complexity of async trait objects, but it is a real constraint for high-concurrency async services.
Diesel migrations are managed through the `diesel_cli` tool and stored in a `migrations/` directory. The `.env.sample` file in the repository shows the environment variable format for database URLs:
PG_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/diesel_testThe schema is generated from migrations using `diesel print-schema`, which outputs a `schema.rs` file that the query builder references. This tight coupling between migration state and the Rust schema file means that a migration run outside of Diesel's tooling can desync the generated schema from the database, causing compile errors that trace back to missing or renamed columns. The `migrations/` directory at the repository root and the examples under `examples/postgres/`, `examples/mysql/`, and `examples/sqlite/` each contain their own migration directories, demonstrating the pattern across backends.
SEA-ORM is an alternative Rust ORM with an async-first design. Where Diesel's query builder generates SQL at compile time, SEA-ORM builds queries at runtime and integrates directly with async runtimes. The trade-off is that Diesel's approach catches more errors at compile time, while SEA-ORM's approach is more flexible for dynamic schema scenarios and async workloads.
License, Sponsorship, and Release Cadence
Diesel is dual-licensed under the Apache License 2.0 and the MIT license. Contributors can choose either license for their contributions, and any contribution submitted without an explicit license statement is treated as dual-licensed under both. The README notes that the NLnet Foundation and the German Prototype Fund are notable large sponsors of Diesel development, which explains the sustained release cadence for a project without a commercial backer.
The release cadence is active: v2.3.11 shipped on 2026-07-10, v2.3.12 on 2026-08-07, and v2.3.13 on 2026-09-04. The last repository push was on 2026-09-25. The `CHANGELOG.md` at the repository root documents changes per release. The `rust-toolchain` file pins the Rust toolchain version used for development, and `clippy.toml` configures the Clippy linter rules used in CI. The `.typos.toml` file configures the typos spell checker, and `deny.toml` configures cargo-deny for dependency auditing.
The `diesel_bench/` crate in the workspace provides benchmarks comparing Diesel against raw SQL and other ORM approaches. The `fuzz/` directory contains fuzzing targets for the query builder. The `docker-compose.yml` at the repository root spins up PostgreSQL, MySQL, and MariaDB containers for running the full test suite locally.
Editorial conclusion
Diesel is the right ORM for Rust projects that prioritize compile-time query verification and want to eliminate runtime database errors through the type system. The minimum Rust version is 1.88.0 (from Cargo.toml). Teams building new Rust applications against PostgreSQL, MySQL, SQLite, or MariaDB will find the codegen macros and query builder well-suited for both simple CRUD operations and complex multi-table queries. Teams that need async database access should evaluate whether Diesel's synchronous design fits their architecture, since Diesel is synchronous by default. The current stable release is v2.3.13, released on 2026-09-04.
Frequently asked questions
What databases does Diesel support?
Diesel supports PostgreSQL, MySQL, SQLite, and MariaDB. Each backend is enabled via a feature flag in Cargo.toml: `features = ["postgres"]` for PostgreSQL, `features = ["mysql"]` for MySQL, `features = ["sqlite"]` for SQLite.
Does Diesel support async Rust?
Diesel's connection model is synchronous by default. The README and documentation at diesel.rs cover the synchronous API. Teams using async runtimes like tokio need to run Diesel queries on a blocking thread pool or use a separate async adapter crate.
How do I get started with Diesel?
Add Diesel to your Cargo.toml with the appropriate backend feature flag, install the diesel_cli tool, and follow the getting started tutorial at https://diesel.rs/guides/getting-started. The CLI sets up the migrations directory and generates the initial schema.rs file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/diesel-rs-diesel)