{"id":13672207,"url":"https://github.com/duckdb/duckdb-rs","last_synced_at":"2026-05-22T09:01:42.884Z","repository":{"id":37939542,"uuid":"374544800","full_name":"duckdb/duckdb-rs","owner":"duckdb","description":" Ergonomic bindings to duckdb for Rust ","archived":false,"fork":false,"pushed_at":"2024-04-12T07:41:24.000Z","size":41209,"stargazers_count":355,"open_issues_count":69,"forks_count":69,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-04-13T00:39:05.082Z","etag":null,"topics":["arrow","database","duckdb","ffi","ffi-bindings","olap","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/duckdb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-06-07T05:27:15.000Z","updated_at":"2024-04-17T09:36:55.538Z","dependencies_parsed_at":"2023-10-04T15:01:57.508Z","dependency_job_id":"c4503630-a511-48b7-8bed-0c2abbb40ff3","html_url":"https://github.com/duckdb/duckdb-rs","commit_stats":null,"previous_names":["wangfenjin/duckdb-rs"],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duckdb%2Fduckdb-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duckdb%2Fduckdb-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duckdb%2Fduckdb-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/duckdb%2Fduckdb-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/duckdb","download_url":"https://codeload.github.com/duckdb/duckdb-rs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247721898,"owners_count":20985084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arrow","database","duckdb","ffi","ffi-bindings","olap","rust"],"created_at":"2024-08-02T09:01:29.291Z","updated_at":"2026-05-22T09:01:42.877Z","avatar_url":"https://github.com/duckdb.png","language":"Rust","funding_links":[],"categories":["Rust","Client APIs","database"],"sub_categories":[],"readme":"# duckdb-rs\n\n[![Latest Version](https://img.shields.io/crates/v/duckdb.svg)](https://crates.io/crates/duckdb)\n[![Documentation](https://img.shields.io/badge/docs.rs-duckdb-orange)](https://docs.rs/duckdb)\n[![MIT License](https://img.shields.io/crates/l/duckdb.svg)](LICENSE)\n[![Downloads](https://img.shields.io/crates/d/duckdb.svg)](https://crates.io/crates/duckdb)\n[![CI](https://github.com/duckdb/duckdb-rs/workflows/CI/badge.svg)](https://github.com/duckdb/duckdb-rs/actions)\n\nduckdb-rs is an ergonomic Rust wrapper for [DuckDB](https://github.com/duckdb/duckdb).\n\nYou can use it to:\n\n- Query DuckDB with type-safe bindings and an API inspired by [rusqlite](https://github.com/rusqlite/rusqlite).\n- Read and write Arrow, Parquet, JSON, and CSV formats natively.\n- Create DuckDB extensions in Rust with custom scalar and table functions.\n\n## Quickstart\n\nCreate a new project and add the `duckdb` crate:\n\n```shell\ncargo new quack-in-rust\ncd quack-in-rust\ncargo add duckdb -F bundled\n```\n\nUpdate `src/main.rs` with the following code:\n\n```rust\nuse duckdb::{params, Connection, Result};\n\nstruct Duck {\n    id: i32,\n    name: String,\n}\n\nfn main() -\u003e Result\u003c()\u003e {\n    let conn = Connection::open_in_memory()?;\n\n    conn.execute(\n        \"CREATE TABLE ducks (id INTEGER PRIMARY KEY, name TEXT)\",\n        [], // empty list of parameters\n    )?;\n\n    conn.execute_batch(\n        r#\"\n        INSERT INTO ducks (id, name) VALUES (1, 'Donald Duck');\n        INSERT INTO ducks (id, name) VALUES (2, 'Scrooge McDuck');\n        \"#,\n    )?;\n\n    conn.execute(\n        \"INSERT INTO ducks (id, name) VALUES (?, ?)\",\n        params![3, \"Darkwing Duck\"],\n    )?;\n\n    let ducks = conn\n        .prepare(\"FROM ducks\")?\n        .query_map([], |row| {\n            Ok(Duck {\n                id: row.get(0)?,\n                name: row.get(1)?,\n            })\n        })?\n        .collect::\u003cResult\u003cVec\u003c_\u003e\u003e\u003e()?;\n\n    for duck in ducks {\n        println!(\"{}) {}\", duck.id, duck.name);\n    }\n\n    Ok(())\n}\n```\n\nExecute the program with `cargo run` and watch DuckDB in action!\n\n## Examples\n\nThe following [examples](crates/duckdb/examples) demonstrate various features and use cases of duckdb-rs:\n\n- **basic** - Basic usage including creating tables, inserting data, and querying with and without Arrow.\n- **appender** - Bulk data insertion using the appender API with transactions.\n- **parquet** - Reading Parquet files directly using DuckDB's Parquet extension.\n- **repl** - Interactive SQL REPL.\n- **hello-ext** - A loadable DuckDB extension.\n\nRun any example with `cargo run --example \u003cname\u003e`.\n\n## Feature flags\n\nThe `duckdb` crate provides a number of Cargo features that can be enabled to add functionality:\n\n### Virtual tables and functions\n\n- `vtab` - Base support for creating custom table functions and virtual tables.\n- `vtab-arrow` - Apache Arrow integration for virtual tables. Enables conversion between Arrow RecordBatch and DuckDB data chunks.\n- `vtab-excel` - Read Excel (.xlsx) files directly in SQL queries with automatic schema detection.\n- `vscalar` - Create custom scalar functions that operate on individual values or rows.\n- `vscalar-arrow` - Arrow-optimized scalar functions for vectorized operations.\n\n### File formats\n\n- `json` - Enables reading and writing JSON files. Implies `bundled`.\n- `parquet` - Enables reading and writing Parquet files. Implies `bundled`.\n\n### Bundled DuckDB extensions\n\nThese extensions are only available through the CMake build backend and imply `bundled-cmake`.\n\n- `autocomplete` - DuckDB's autocomplete extension.\n- `icu` - DuckDB's ICU extension for locale-aware operations.\n- `tpch` - DuckDB's TPC-H benchmark extension.\n- `tpcds` - DuckDB's TPC-DS benchmark extension.\n\n### Data integration\n\n- `appender-arrow` - Efficient bulk insertion of Arrow data into DuckDB tables.\n- `polars` - Integration with Polars DataFrames.\n\n### Convenience features\n\n- `vtab-full` - Enables all virtual table features: `vtab-excel`, `vtab-arrow`, and `appender-arrow`.\n- `extensions-full` - Enables all major extensions: `json`, `parquet`, and `vtab-full`.\n- `modern-full` - Enables modern Rust ecosystem integrations: `chrono`, `serde_json`, `url`, `r2d2`, `uuid`, and `polars`.\n\n### Build configuration\n\n- `bundled` - Uses a bundled version of DuckDB's source code and compiles it during build. This is the simplest way to get started and avoids needing DuckDB system libraries.\n- `bundled-cmake` - *Experimental*. Builds DuckDB via its upstream CMake build system instead of `cc`. Requires a duckdb-rs checkout (not available from crates.io). See [step 2](#notes-on-building-duckdb-and-libduckdb-sys) below for details.\n- `buildtime_bindgen` - Use bindgen at build time to generate fresh bindings instead of using pre-generated ones.\n- `loadable-extension` - _Experimental_ support for creating loadable DuckDB extensions. Includes procedural macros for extension development.\n\n## Installation\n\n### Versioning\n\nStarting with DuckDB `v1.5.0`, the duckdb-rs version encodes the DuckDB version in its second semver component.\nThe format is `1.MAJOR_MINOR_PATCH.x`, e.g., DuckDB `v1.5.0` maps to duckdb-rs `1.10500.x`.\n\n### Using stable releases from crates.io\n\nThe recommended way to use duckdb-rs is to add it from crates.io:\n\n```shell\ncargo add duckdb -F bundled\n```\n\nOr manually add it to your `Cargo.toml`:\n\n```toml\n[dependencies]\nduckdb = { version = \"=1.10503.0\", features = [\"bundled\"] }\n```\n\n### Using the development version from git\n\nTo use the latest development version from the main branch, you can specify a git dependency in your `Cargo.toml`:\n\n```toml\n# Use a specific branch\nduckdb = { git = \"https://github.com/duckdb/duckdb-rs\", branch = \"main\", features = [\"bundled\"] }\n\n# Use a specific commit\nduckdb = { git = \"https://github.com/duckdb/duckdb-rs\", rev = \"abc123def\", features = [\"bundled\"] }\n```\n\nNote: Using the main branch of duckdb-rs means you'll get the latest Rust bindings and features, but you'll still be using whatever version of DuckDB core is bundled with that commit (when using the `bundled` feature).\n\n## Notes on building duckdb and libduckdb-sys\n\n`libduckdb-sys` is a separate crate from `duckdb-rs` that provides the Rust\ndeclarations for DuckDB's C API. By default, `libduckdb-sys` attempts to find a DuckDB library that already exists on your system using pkg-config, or a\n[Vcpkg](https://github.com/Microsoft/vcpkg) installation for MSVC ABI builds.\n\nYou can adjust this behavior in a number of ways:\n\n1. If you use the `bundled` feature, `libduckdb-sys` will use the\n   [cc](https://crates.io/crates/cc) crate to compile DuckDB from source and\n   link against that. This source is embedded in the `libduckdb-sys` crate and\n   tracks the DuckDB version vendored for that duckdb-rs release.\n   This is probably the simplest solution to any build problems. You can enable this by adding the following in your `Cargo.toml` file:\n\n   ```bash\n   cargo add duckdb --features bundled\n   ```\n\n   `Cargo.toml` will be updated.\n\n   ```toml\n   [dependencies]\n   duckdb = { version = \"1.10503.0\", features = [\"bundled\"] }\n   ```\n\n2. If you use the `bundled-cmake` feature, `libduckdb-sys` will build DuckDB from the local checkout in `crates/libduckdb-sys/duckdb-sources` using upstream CMake. This keeps plain `bundled` unchanged while allowing CMake-only extensions such as `icu`.\n\n   Example:\n\n   ```toml\n   [dependencies]\n   duckdb = { git = \"https://github.com/duckdb/duckdb-rs\", branch = \"main\", features = [\"bundled-cmake\", \"icu\"] }\n   ```\n\n   Notes:\n\n   - `bundled-cmake` is *experimental* and requires a git/workspace checkout. It is not available from crates.io because the full `duckdb-sources` tree is not packaged there.\n   - `bundled-cmake` implies `bundled` (for conditional-compilation gates) but replaces the `cc` build backend with CMake. Enabling any CMake-only extension feature (e.g. `icu`) automatically activates `bundled-cmake`.\n   - `bundled-cmake` always links DuckDB's default static extensions (`core_functions` and `parquet`), so it also implies the `parquet` Cargo feature.\n   - The plain `bundled` backend uses DuckDB's standard allocator and does not build jemalloc. On supported 64-bit, non-musl Linux targets, `bundled-cmake` builds DuckDB with upstream's jemalloc allocator enabled; on other targets, DuckDB's CMake platform checks leave jemalloc disabled. Set `DUCKDB_DISABLE_JEMALLOC=1` in the build environment to force `bundled-cmake` to use DuckDB's standard allocator.\n   - Extension autoload/autoinstall are forced on to match the existing `bundled` backend, even though upstream CMake defaults are off. If `DUCKDB_DISABLE_EXTENSION_LOAD=1` is set, both defaults are forced off as well.\n   - When `ninja` is on `PATH`, the Ninja generator is preferred automatically. Set `CMAKE_GENERATOR` to override.\n   - Builds DuckDB in `Release` mode by default, even in Rust debug builds, to avoid DuckDB's much slower debug/sanitizer profile. Set `DUCKDB_CMAKE_BUILD_TYPE` or `CMAKE_BUILD_TYPE` to override. `DUCKDB_CMAKE_BUILD_TYPE` takes precedence.\n   - Setting `DUCKDB_DISABLE_EXTENSION_LOAD=1` (or `DISABLE_EXTENSION_LOAD=1`) in the build environment compiles DuckDB without external extension install/load support. Statically linked extensions remain available.\n   - `DUCKDB_EXTENSION_CONFIGS` is not yet supported; the build fails fast rather than producing a broken binary.\n   - Use `cargo build -vv -F bundled-cmake` to surface CMake configure/build logs.\n\n3. When linking against a DuckDB library already on the system (so _not_ using any of the `bundled` features), you can set the `DUCKDB_LIB_DIR` environment variable to point to a directory containing the library. You can also set the `DUCKDB_INCLUDE_DIR` variable to point to the directory containing `duckdb.h`.\n\n   Linux example:\n\n   ```shell\n   wget https://github.com/duckdb/duckdb/releases/download/v1.5.3/libduckdb-linux-arm64.zip\n   unzip libduckdb-linux-arm64.zip -d libduckdb\n\n   export DUCKDB_LIB_DIR=$PWD/libduckdb\n   export DUCKDB_INCLUDE_DIR=$DUCKDB_LIB_DIR\n   export LD_LIBRARY_PATH=$DUCKDB_LIB_DIR\n\n   cargo build --examples\n   ```\n\n   macOS example:\n\n   ```shell\n   wget https://github.com/duckdb/duckdb/releases/download/v1.5.3/libduckdb-osx-universal.zip\n   unzip libduckdb-osx-universal.zip -d libduckdb\n\n   export DUCKDB_LIB_DIR=$PWD/libduckdb\n   export DUCKDB_INCLUDE_DIR=$DUCKDB_LIB_DIR\n   export DYLD_FALLBACK_LIBRARY_PATH=$DUCKDB_LIB_DIR\n\n   cargo build --examples\n   ```\n\n4. Setting `DUCKDB_DOWNLOAD_LIB=1` makes the build script download pre-built DuckDB binaries from GitHub Releases. This always links against the dynamic library in the archive (setting `DUCKDB_STATIC` has no effect), and it effectively automates the manual steps above. The archives are cached in `target/duckdb-download/\u003ctarget\u003e/\u003cversion\u003e` and that directory is automatically added to the linker search path. The downloaded version always matches the DuckDB version encoded in the `libduckdb-sys` crate version.\n\n   ```shell\n   DUCKDB_DOWNLOAD_LIB=1 cargo test\n   ```\n\n5. Installing the DuckDB development packages will usually be all that is required, but\n   the build helpers for [pkg-config](https://github.com/alexcrichton/pkg-config-rs)\n   and [vcpkg](https://github.com/mcgoo/vcpkg-rs) have some additional configuration\n   options. The default when using vcpkg is to dynamically link,\n   which must be enabled by setting `VCPKGRS_DYNAMIC=1` environment variable before build.\n\nWhen none of the options above are used, the build script falls back to this discovery path and will emit the appropriate `cargo:rustc-link-lib` directives if DuckDB is found on your system.\n\n### ICU extension and the bundled features\n\nWhen using the `bundled` feature, the ICU extension is not included due to crates.io's 10MB package size limit. This means some date/time operations (like `now() - interval '1 day'` or `ts::date` casts) will fail. You can load ICU at runtime:\n\n```rust,ignore\nconn.execute_batch(\"INSTALL icu; LOAD icu;\")?;\n```\n\nAlternatively, link against a system libduckdb that was compiled with ICU (see build instructions above).\n\nIf you are working from a duckdb-rs checkout, you can also use `bundled-cmake,icu` to compile ICU in through DuckDB's CMake build.\n\n### Binding generation\n\nWe use [bindgen](https://crates.io/crates/bindgen) to generate the Rust\ndeclarations from DuckDB's C header file. `bindgen`\n[recommends](https://github.com/servo/rust-bindgen#library-usage-with-buildrs)\nrunning this as part of the build process for libraries that use it. We tried\nthis briefly (`duckdb` 0.10.0, specifically), but it had some annoyances:\n\n- The build time for `libduckdb-sys` (and therefore `duckdb`) increased\n  dramatically.\n- Running `bindgen` requires a relatively recent version of Clang, which many\n  systems do not have installed by default.\n- Running `bindgen` also requires the DuckDB header file to be present.\n\nSo we try to avoid running `bindgen` at build time by shipping\npregenerated bindings for DuckDB.\n\nIf you use the `bundled` feature, you will get pregenerated bindings for the\nbundled version of DuckDB. If you want to run `bindgen` at build time to\nproduce your own bindings, use the `buildtime_bindgen` Cargo feature.\n\n## Rust version compatibility\n\nduckdb-rs is built and tested with stable Rust, and keeps a rolling MSRV (minimum supported Rust version) that may only be updated when the encoded DuckDB major/minor version changes, on a need basis (e.g. project dependencies bump their MSRV or a particular Rust feature is useful for us). The new MSRV will be at least 6 months old. DuckDB patch updates and crate patch releases (e.g. `1.10500.0` to `1.10500.1`) are guaranteed to keep the same MSRV.\n\n## Contributing\n\nWe welcome contributions! Take a look at [CONTRIBUTING.md](CONTRIBUTING.md) for more information.\n\nJoin our [Discord](https://discord.gg/tcvwpjfnZx) to chat with the community in the #rust channel.\n\n## License\n\nCopyright (c) Stichting DuckDB Foundation\n\nLicensed under the [MIT license](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduckdb%2Fduckdb-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fduckdb%2Fduckdb-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fduckdb%2Fduckdb-rs/lists"}