> ## Documentation Index
> Fetch the complete documentation index at: https://better-duck.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Diesel Backend Overview

> What the better-duck-diesel Diesel 2.3 backend for DuckDB is, how it builds on better-duck-core, its feature flags, and when to reach for the ORM vs the raw core driver.

`better-duck-diesel` is a third-party [Diesel](https://diesel.rs) 2.3 backend for DuckDB. It plugs the
[`better-duck-core`](/core/opening-connections) driver into Diesel's typed query builder, so you connect, map a
schema with `table!`, and build `INSERT`/`SELECT`/`UPDATE`/`DELETE` queries as Rust — while still
reaching the DuckDB-specific SQL (operators, scalar functions, aggregates, types) that stock Diesel has
no equivalent for.

DuckDB itself is compiled and embedded through core, so there is no system install and no `libduckdb` to
link against.

## What it is

`DuckDbConnection` is a full Diesel `Connection` + `LoadConnection`. That means:

* `conn.transaction(|c| …)` and `begin_test_transaction` work — see [Transactions](/diesel/transactions).
* Prepared-statement caching and instrumentation work.
* `r2d2` pooling works — see [Pooling](/diesel/pooling).
* `diesel migration` works — the connection implements `MigrationConnection`, see [Schema & Migrations](/diesel/schema#migrations).
* `.inner()` / `.inner_mut()` expose the underlying core `Connection` for registering UDFs, loading
  extensions, and running core-only APIs — see [Installation & Setup](/diesel/installation-and-setup#reaching-the-core-connection).

<Note>
  This crate's default feature set is `["decimal"]` only. Unlike `better-duck-core`, **`chrono` is NOT on
  by default here** — turn it on for date/time column support. See [Feature flags](#feature-flags) below.
</Note>

## 30-second quickstart

```toml theme={null}
[dependencies]
better-duck-diesel = "0.1.0-beta.8"
diesel = "2.3"
```

```rust theme={null}
use better_duck_diesel::DuckDbConnection;
use diesel::prelude::*;

diesel::table! {
    products (id) {
        id    -> Integer,
        name  -> Text,
        price -> Double,
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // `:memory:` or a file path; a leading `duckdb://` is stripped.
    let mut conn = DuckDbConnection::establish(":memory:")?;
    conn.batch_execute(
        "CREATE TABLE products (id INTEGER PRIMARY KEY, name VARCHAR NOT NULL, price DOUBLE NOT NULL)",
    )?;

    diesel::insert_into(products::table)
        .values((products::id.eq(1), products::name.eq("widget"), products::price.eq(9.99)))
        .execute(&mut conn)?;

    let rows: Vec<(i32, String, f64)> = products::table
        .filter(products::price.lt(20.0))
        .order(products::name.asc())
        .load(&mut conn)?;
    assert_eq!(rows, [(1, "widget".to_string(), 9.99)]);
    Ok(())
}
```

See [Installation & Setup](/diesel/installation-and-setup) for the full connection surface and
[Schema](/diesel/schema) for mapping tables.

## The two SQL surfaces

Diesel core already gives you the **portable** surface, and it works on `DuckDbConnection` with no extra
imports: `=`/`<`/`>`, `LIKE`, `count`/`sum`/`avg`/`min`/`max`, `.filter`/`.order`/`.limit`, joins,
`insert_into`/`update`/`delete`, `RETURNING`, `ON CONFLICT`.

The **DuckDB-only** surface lives behind one import, brought in alongside Diesel's prelude:

```rust theme={null}
use diesel::prelude::*;
use better_duck_diesel::dsl::*;
```

That prelude adds two operator extension traits (`DuckExpressionMethods`, `DuckTextExpressionMethods`)
plus a large library of typed free functions and aggregates — all emitting real DuckDB SQL, none
requiring `sql_query`. See the [DSL overview](/diesel/dsl-overview) for the map of this surface.

<Note>
  Spatial `ST_*` functions are **not** in the `dsl::*` prelude — import them from
  `better_duck_diesel::spatial::*` under `feature = "spatial"`. See [Spatial](/diesel/spatial).
</Note>

## Feature flags

Verified against `crates/better-duck-diesel/Cargo.toml`.

| Feature | Default | Enables |
| - | - | - |
| `decimal` | ✓ | Diesel `Numeric` ↔ `rust_decimal::Decimal` (forwards to core `decimal`) |
| `chrono` | — | Diesel date/time impls (DATE, TIME, TIMESTAMP, TIMESTAMPTZ, INTERVAL, TIME\_TZ, TIME\_NS) |
| `r2d2` | — | r2d2 pooling: `diesel::r2d2` support + `pool::SharedDuckDbConnectionManager` |
| `udf` | — | expose the core connection for registering `#[duckdb_*]` UDFs, callable in the DSL |
| `spatial` | — | the `spatial` module: `ST_*` DSL functions + `ensure_loaded` |
| `json` | — | bundle DuckDB's JSON extension so the JSON DSL works offline (forwards to core `json`) |
| `derive` | — | re-export `FromRow`/`ToRow`/`DuckEnum`/`DuckStruct` with Diesel `FromSql`/`ToSql` emission on |

<Warning>
  There is **no `bundled` feature** on this crate (an older README feature table listed one, but
  `Cargo.toml` does not define it). DuckDB is embedded through core regardless. The `spatial` feature
  carries no extra Rust deps — it only gates the module; the `ST_*` functions are plain SQL, and
  `ensure_loaded` installs/loads the extension at runtime (needs network unless already present).
</Warning>

For the full project-wide feature picture, see [feature flags](/guide/feature-flags).

## When to use the ORM vs raw core

Reach for `better-duck-diesel` when you want a typed query builder, schema mapping, migrations, or
pooling over DuckDB.

Drop to [`better-duck-core`](/core/opening-connections) whenever you need something below the ORM — the appender
for bulk insert, columnar chunks, async, Arrow/Polars interop, or raw parameter binding. Those are **not**
part of the Diesel surface. Because `DuckDbConnection::inner_mut()` hands you the core `Connection`, you
can mix both in the same program. See [Choosing an API](/guide/choosing-an-api).

## Sibling crates

<CardGroup cols={2}>
  <Card title="better-duck-core" href="/core/opening-connections">
    The raw Rust driver: connections, values, appender, columnar chunks, async.
  </Card>

  <Card title="UDF & derive macros" href="/macros/udf-overview">
    The `#[duckdb_*]` UDF macros and `FromRow`/`DuckEnum`/`DuckStruct` derives.
  </Card>

  <Card title="DuckDB SQL DSL" href="/diesel/dsl-overview">
    DuckDB-only operators, scalar functions, aggregates, and spatial.
  </Card>

  <Card title="Type mapping" href="/diesel/type-mapping">
    Rust ↔ DuckDB type mapping and the `values::*` binding newtypes.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.