The communityDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nimdeveloper/better-duck/llms.txt
Use this file to discover all available pages before exploring further.
duckdb crate is a mature DuckDB binding for Rust, but it requires Arrow for column I/O, depends on libduckdb-sys (which historically required a separately managed system library or a large bundle step), and does not have a Diesel ORM backend. better-duck-core takes a different path: DuckDB is compiled from vendored source unconditionally, Arrow is never a dependency, and better-duck-diesel provides a full Diesel 2.3 backend on top. If you are migrating an existing project, most of the common operations map directly — the surface-level differences are small.
Operation Comparison
The table below shows the most common operations side by side. Rows marked as identical work without any code changes.| Operation | duckdb crate | better-duck-core |
|---|---|---|
| Open in-memory | Connection::open_in_memory()? | Connection::open_in_memory()? |
| Execute DDL | conn.execute_batch(sql)? | conn.execute_batch(sql)? |
| Insert / DML | conn.execute(sql, [])? | conn.execute(sql)?.changes() |
| SELECT rows | conn.prepare(sql)?.query([]) | conn.execute(sql)? (is an Iterator) |
| Parameterized | conn.execute(sql, params![v])? | conn.execute_with(sql, &mut [&mut v])? |
| Bulk insert | conn.appender(table)? | conn.appender(table, schema)? |
Key Differences
1. execute returns an Iterator directly
In the duckdb crate, reading rows requires a separate prepare + query call:
execute returns a DuckResult which is already an Iterator over Result<DuckRow>:
.changes() on the returned DuckResult to get the number of affected rows:
2. Parameters use &mut [&mut dyn AppendAble] instead of params![]
The duckdb crate uses a params![] macro backed by ToSql:
$1, $2, … (1-based) and passed as a mutable slice of AppendAble references:
AppendAble can be used directly — you are not limited to DuckValue. See the types::appendable module for the trait definition.
3. appender requires an explicit schema name
The duckdb crate’s appender method takes only the table name:
"main" for the default schema:
4. DuckValue instead of Arrow-backed types
The duckdb crate represents column values as Arrow arrays when the Arrow feature is enabled, or as generic duckdb::types::Value variants. better-duck-core uses DuckValue, a non-exhaustive enum covering the full DuckDB type hierarchy without any Arrow dependency:
DuckValue is #[non_exhaustive] — always include a _ wildcard arm.
5. No Arrow dependency
better-duck-core has no dependency onarrow, arrow2, or any Arrow-ecosystem crate. If your migration path requires Arrow interop, you will need to convert DuckValue rows to Arrow arrays manually (or keep a thin adapter layer) — this is intentional by design to avoid pulling Arrow into embedded and Tauri applications.
Removed Features
As of beta.4, thebundled feature flag no longer exists. DuckDB is compiled from vendored source unconditionally via the new better-duck-sys crate — there is no “system library” build mode. If your Cargo.toml references features = ["bundled"], remove it:
buildtime_bindgen feature is still present but is only needed by maintainers to regenerate the pre-checked-in FFI bindings using LLVM/clang. Ordinary consumers never need it.