Open-source project
diesel-rs/diesel avatar
diesel-rs/diesel

Diesel (Rust ORM): a type-checked query builder for PostgreSQL, MySQL, MariaDB and SQLite

A safe, extensible ORM and Query Builder for Rust

14,249 stars1,258 forksRustApache-2.0

At a glance

What is it?
Diesel is a Rust ORM and query builder that pushes SQL mistakes into compile errors. This article covers what it does, how the query builder and codegen work, how to install it, and where it stops being the right tool.
Who is it for?
Adopt Diesel when your team writes Rust, your schema is stable enough to generate code against, and you want SQL errors surfaced by the compiler rather than in production. Skip it when you need one query layer shared with non-Rust services, or when you want to hand-tune every statement.
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 received new commits within the last day.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • diesel-rs/diesel14,249 ★ · +68
Star history
Repository2026-09-222026-11-14
diesel-rs/diesel14.2k14.2k

68 Stars in the last 53 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

What Diesel solves, and who ends up using it

Hand-written SQL in application code fails in a specific way: the mistake is invisible until runtime. A column renamed in a migration, a type that does not match the Rust struct, a filter applied to the wrong table. Diesel's answer is to move those checks into the compiler. The README frames the goal as eliminating runtime errors without sacrificing performance, and describes a query builder that "feels like Rust."

The intended audience is Rust teams that own their schema and are willing to let a build step read it. The repository ships a workspace with separate crates for the core library, the derives, the CLI, migrations, a dynamic schema escape hatch, and a set of runnable examples per backend. That layout tells you what the maintainers expect: you generate code from a database, you keep migrations in the repo, and you run the examples against a real server rather than a mock.

If your application is mostly CRUD over tables you control, Diesel removes a category of boilerplate. If your application is mostly analytics queries written by a data team in another language, the type system has less to offer you.

How the query builder and codegen actually fit together

Diesel is two things that meet in the middle. The first is a set of types that represent SQL fragments, so that a query is built by composing values rather than concatenating strings. The second is generated Rust code describing your tables, which is what makes the first part type-safe.

The README's own examples show the shape. `users::table.load(&mut connection)` produces `SELECT * FROM users;`. A relation method generates the join condition for you: `Post::belonging_to(user).load(&mut connection)` becomes `SELECT * FROM posts WHERE user_id = 1;`. Chained methods compose into a single statement, and the README shows a nested subquery built from `Version::belonging_to(krate).select(id).order(num.desc()).limit(5)` used inside `version_id.eq_any(versions)`.

The codegen half is where the table names and column types come from. In the README's example, `#[derive(Queryable, Selectable)]` with `#[diesel(table_name = downloads)]` lets a struct be loaded without hand-written row mapping. The README contrasts this with an implementation that pulls each field out of a row by name, which is the code you would otherwise maintain by hand.

There is a deliberate escape hatch. When a query cannot be expressed in the builder, `sql_query` accepts raw SQL, and `#[derive(QueryableByName)]` maps the result. The README's example keeps the SQL in a separate file through `include_str!` so the editor can still highlight it, and binds parameters with explicit types via `.bind::<Integer, _>(organization_id)`. That is a reasonable compromise, but note that raw queries are outside the compile-time checking that motivates the library in the first place.

Installing Diesel and running a first query

Diesel is published on crates.io. The README gives the dependency declaration and states that the backend is selected by feature flag, so you enable the feature for your database.

toml
[dependencies]
diesel = { version = "<version>", features = ["<postgres|mysql|sqlite>"] }

The README points at the Getting Started tutorial at https://diesel.rs/guides/getting-started for the full walkthrough rather than reproducing the CLI steps inline. The repository layout confirms a `diesel_cli/` crate and a `diesel_migrations/` crate, which is where the command-line tooling and migration support live. The README does not list the CLI installation command, so check the guide for the current form before running it.

For local development, the repository provides a `docker-compose.yml` that starts the supported servers with the credentials its own test suite expects. Postgres is published on port 5432 with the password `postgres`, MySQL on 3306 with an empty root password, and MariaDB on 3307 mapped to the container's 3306 with an empty root password.

yaml
services:
  postgres:
    image: postgres
    environment:
      POSTGRES_PASSWORD: "postgres"
    ports:
      - "5432:5432"

The repository also ships `.env.sample`, which names the environment variables used when running tests and examples, for example `PG_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/diesel_test` and `MYSQL_DATABASE_URL=mysql://[email protected]:3306/diesel_test`. That file carries a warning worth reading before you copy it: special characters in connection URLs must be URL-encoded, because the underlying `url` crate parses the URL strictly, unlike Postgres's native connection string format. The file gives the example that `postgresql://username@/dbname?host=/var/run/postgresql` is incorrect and `postgresql://username@%2Fvar%2Frun%2Fpostgresql/dbname` is correct.

Once the dependency and the generated schema are in place, a first read looks like the README's simplest example, and a first write uses an `Insertable` struct passed to `insert_into(users).values(&new_users)`. The README notes that switching `execute` to `get_result` or `get_results` returns the inserted rows, which becomes a `RETURNING *` clause in the generated SQL.

Where Diesel gets in your way

The compile-time checking is the selling point and also the main cost. Generated table definitions have to exist before the rest of your code compiles, so the generated schema code has to be kept in step with your database. The repository ships a `diesel_dynamic_schema/` crate, which suggests the maintainers know static generation does not fit every workflow, but the dynamic path gives up the type guarantees that justify choosing Diesel.

Compile times are the second cost. A query builder that encodes SQL structure in Rust types produces long monomorphised chains, and errors from a malformed query can be verbose because the compiler is reporting a trait bound failure rather than a SQL syntax error. The workspace pins `rust-version = "1.88.0"` and edition 2024, so older toolchains are not an option.

Diesel is also the wrong tool when the database is not yours to generate against. If the schema is owned by another team and changes without notice, or if you are querying a warehouse whose DDL you never see, the generated code becomes a maintenance burden rather than a safety net. The same applies when several services in different languages must share one query layer: Diesel's abstractions do not travel outside Rust.

Finally, the README is explicit that raw SQL is sometimes easier or simply not expressible in the builder. That is honest, but it means a real application ends up with two query styles, and the raw ones receive none of the checking.

Diesel compared with sqlx

The most common alternative in the Rust ecosystem is sqlx, and the difference is philosophical rather than cosmetic. sqlx keeps SQL as a string in your source and verifies it against a live database at compile time through its macros, or leaves it unchecked when you use the runtime API. Diesel builds the query from Rust values and checks it through the type system, with the SQL generated for you.

That shows up in daily work. With sqlx you write the `SELECT` and get back a row type; the query is the artifact you review. With Diesel you write method chains and read the generated SQL in the README's examples to confirm what will run. Diesel's approach makes composition easier, since a subquery is a value you can pass to `eq_any` rather than a string you concatenate. sqlx's approach makes it easier to paste a query from a database console or a colleague's ticket and keep it readable.

The real split is whether you want the SQL to be the source of truth or a derived output. Diesel also covers migrations through its own crates, which sqlx does as well, so that is not decisive either. Pick based on which artifact your team is more comfortable reviewing.

Maintenance, releases and licensing

The repository is not archived, and the last push was on 2026-11-02. Recent releases are close together: v2.3.12 on 2026-08-07, v2.3.13 on 2026-09-04, and v2.3.14 on 2026-10-07. That cadence is consistent with a project that ships patch releases on a monthly rhythm, and the presence of a CHANGELOG.md at the repository root means upgrade notes have a home. Treat the changelog as the authoritative record and read it before bumping.

Upgrade cost in a Diesel application is not only the crate version. Because table definitions are generated, a new release can change the shape of generated code, which means regeneration is part of the upgrade. The workspace's own `rust-version = "1.88.0"` is a useful signal of the minimum toolchain the maintainers test against.

On licensing, the README states the project is licensed under either the Apache License, Version 2.0 or the MIT license, and that contributions are dual-licensed on the same terms unless stated otherwise. The repository root contains LICENSE-APACHE and LICENSE-MIT, which matches. Dual licensing under permissive terms is generally straightforward for commercial use, but the choice between the two and any notice obligations depend on your own distribution model, which is a question for your legal counsel rather than something this article can settle.

Editorial conclusion

Adopt Diesel when your team writes Rust, your schema is stable enough to generate code against, and you want SQL errors surfaced by the compiler rather than in production. Skip it when you need one query layer shared with non-Rust services, or when you want to hand-tune every statement. Before committing, verify that your database backend is one of the four supported, check that your toolchain satisfies the workspace rust-version of 1.88.0, and confirm the diesel_cli can connect to your database so that schema.rs generation works in CI.

Frequently asked questions

Which databases does Diesel support?

The README lists PostgreSQL, MySQL, SQLite and MariaDB, and the backend is chosen through a feature flag in Cargo.toml.

Does Diesel require a database at build time?

Diesel's codegen generates the table definitions and row-mapping boilerplate that the rest of the code compiles against, so those must exist before you build. The repository also ships a dynamic schema crate for workflows where static generation does not fit.

Can I use Diesel with raw SQL?

Yes. The README shows `sql_query` with `#[derive(QueryableByName)]`, binding typed parameters with `.bind::<Integer, _>(...)`, and notes that some queries are easier as raw SQL or cannot be expressed in the builder.

What licence is Diesel released under?

The README states it is licensed under either the Apache License, Version 2.0 or the MIT license, with contributions dual-licensed on the same terms.

Official sources

  1. diesel-rs/diesel on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/diesel-rs-diesel.svg)](https://hysenlabs.com/projects/diesel-rs-diesel)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/diesel-rs-diesel.svg)](https://hysenlabs.com/projects/diesel-rs-diesel)

Was this useful?