The Rust SDK for building DuckDB loadable extensions — no C++ required.

CI Crates.io Documentation License: MIT MSRV: 1.84.1


What is quack-rs?

quack-rs is a production-grade Rust SDK that makes building DuckDB loadable extensions straightforward and safe. It wraps the DuckDB C Extension API — the same API used by official DuckDB extensions — and eliminates every known FFI pitfall so you can focus on writing extension logic in pure Rust.

DuckDB's own documentation acknowledges the gap:

"Writing a Rust-based DuckDB extension requires writing glue code in C++ and will force you to build through DuckDB's CMake & C++ based extension template. We understand that this is not ideal and acknowledge the fact that Rust developers prefer to work on pure Rust codebases."

DuckDB Community Extensions FAQ

quack-rs closes that gap. No C++. No CMake. No glue code.


What you can build

Extension typequack-rs support
Scalar functionsScalarFunctionBuilder
Overloaded scalarsScalarFunctionSetBuilder
Aggregate functionsAggregateFunctionBuilder
Overloaded aggregatesAggregateFunctionSetBuilder
Table functionsTableFunctionBuilder
Cast / TRY_CAST functionsCastFunctionBuilder
Replacement scansReplacementScanBuilder
SQL macros (scalar)SqlMacro::scalar
SQL macros (table)SqlMacro::table
Copy functions (COPY TO)CopyFunctionBuilder (requires duckdb-1-5)

Note: Window functions have no counterpart in DuckDB's public C Extension API and cannot be implemented from Rust (or any language) via that API. See Known Limitations.


Why does this exist?

quack-rs was extracted from duckdb-behavioral, a production DuckDB community extension. Building that extension revealed 16 undocumented pitfalls in DuckDB's Rust FFI surface — struct layouts, callback contracts, and initialization sequences that aren't covered anywhere in the DuckDB documentation or libduckdb-sys docs.

Three of those pitfalls caused extension-breaking bugs that passed 435 unit tests before being caught by end-to-end tests:

  1. A SEGFAULT on load (wrong entry point sequence)
  2. 6 of 7 functions silently not registered (undocumented function-set naming rule)
  3. Wrong aggregate results under parallel plans (combine callback not propagating configuration fields to fresh target states)

quack-rs makes each of these impossible through type-safe builders and safe wrappers. The full catalog is documented in the Pitfall Reference.


Key features

  • Zero C++ — no CMakeLists.txt, no header files, no glue code
  • All C API function types — scalar, aggregate, table, cast, replacement scan, SQL macro, copy function (duckdb-1-5)
  • Panic-free FFIinit_extension never panics; errors surface via Result
  • RAII memory managementLogicalType and FfiState<T> prevent leaks and double-frees
  • Type-safe buildersScalarFunctionBuilder, AggregateFunctionBuilder, TableFunctionBuilder, CastFunctionBuilder, ReplacementScanBuilder
  • SQL macros — register CREATE MACRO statements without any FFI callbacks
  • Testable stateAggregateTestHarness<T> tests aggregate logic without a live DuckDB
  • Scaffold generator — produces a submission-ready community extension project from code
  • 16 pitfalls documented — every known DuckDB Rust FFI pitfall, with symptoms and fixes

New to DuckDB extensions? → Start with Quick Start

Adding quack-rs to an existing project? → See Installation

Writing your first function? → See Scalar Functions or Aggregate Functions

Want SQL macros without FFI callbacks? → See SQL Macros

Submitting a community extension? → See Community Extensions

Something broke? → See Pitfall Catalog