Skip to main content
DuckDB’s functionality extends through extensions. better-duck-core lets you load them at runtime, bundle a few at build time, and build your own loadable extension.

Runtime extension management

These Connection methods drive INSTALL / LOAD and read duckdb_extensions(), so a feature can check for an extension and force it to load rather than failing later with an opaque SQL error.
Extension names must be bare identifiers ([A-Za-z0-9_]+); anything else is rejected up front, so the name can be embedded in SQL safely. Runtime loading needs network/filesystem access and enable_external_access (default on). The Diesel spatial module’s ensure_loaded wraps this for the ST_* DSL — see the Diesel docs.

Bundled extensions (build-time features)

The core features json, parquet, and icu compile that DuckDB extension into the static library (forwarded to better-duck-sys), so it is available with no runtime INSTALL / LOAD — ideal for offline/embedded builds (Tauri, iOS, air-gapped servers).
icu adds timezone/collation support and requires a DuckDB archive re-vendored with ICU sources. See feature flags for how to enable each bundled extension.

Loadable extensions (experimental)

The loadable-extension feature builds for a loadable .duckdb_extension: it links no DuckDB and routes every FFI call through the host’s dynamically-loaded API table, so the crate builds a cdylib that a running DuckDB loads. It implies udf and pairs with the #[duckdb_entrypoint] macro, which generates the C-ABI entrypoint.
This is distinct from using extensions as above — it is how you author one. The generated entrypoint symbol is <name>_init_c_api, and extension_api::c_api_init (exposed under the same feature) initializes the host API table.

See also

  • Errors — Error::Engine with EngineErrorKind::MissingExtension / Autoload.
  • #[duckdb_entrypoint] — authoring loadable extensions.
  • Configuration — enable_external_access, allow_unsigned_extensions.
  • Feature flags — json, parquet, icu, loadable-extension.