> ## 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.

# Overview

> A Tauri v2 plugin that exposes embedded DuckDB (better-duck) to the webview as a local analytics engine, with a fixed command set, pluggable backends, and a two-layer security model.

`better-duck-tauri` is a [Tauri v2](https://tauri.app) plugin that exposes
[better-duck](/core/opening-connections) (embedded DuckDB) to the webview as a local **analytics**
engine — not just a CRUD bridge. The Rust side registers the plugin on `tauri::Builder` with a
chosen backend; the frontend talks to it through the `@better-duck/tauri` npm package, which wraps
a fixed set of `invoke` commands.

<Info>
  This documents version **0.1.0-beta.8**. The crate is beta: query, analytics, migration, and
  security features are implemented and tested; the `arrow` (Arrow IPC) command and Android CI are
  the pending edges.
</Info>

## Architecture

Three layers, with the plugin as the trust boundary between an untrusted webview and the embedded
database:

```
┌─────────────┐   invoke('plugin:…|cmd')   ┌──────────────────┐   DuckBackend    ┌──────────┐
│   Webview   │ ─────────────────────────▶ │  better-duck-    │ ───────────────▶ │  DuckDB  │
│  (JS / TS)  │ ◀───── JSON rows / err ──── │  tauri (Rust)    │ ◀─── rows ─────  │ (vendored)│
└─────────────┘                            └──────────────────┘                  └──────────┘
   @better-duck/tauri                      capabilities + scope + Policy          better-duck-core
   Database class                          enforced before the backend runs
```

* **Webview** holds a `Database` handle and calls typed methods that `invoke` plugin commands.
* **Plugin** validates every call against the Tauri capability (which commands are allowed) and the
  scope + `Policy` (which values those commands may use), then runs DuckDB work on a blocking task
  so the async runtime is never blocked.
* **DuckDB** is compiled into the app via `better-duck-core` (vendored through `better-duck-sys`),
  so there is no system install to manage.

## How it fits together

* **One backend, picked by a Cargo feature.** `backend-core` (default) builds on
  `better-duck-core`; `backend-diesel` builds on `better-duck-diesel` (an r2d2 pool of
  `DuckDbConnection` + Diesel `embed_migrations!`). The webview command surface is **identical**
  either way — both engines implement the same `DuckBackend` trait, so your JS never changes. See
  [Backends](/tauri/backends).
* **A fixed command set**, not arbitrary RPC. Every command is a `#[tauri::command]` and is listed
  in `build.rs` so Tauri can generate its `allow-*` / `deny-*` permissions.
* **Two security layers**: an init-time Rust [`Policy`](/tauri/scope-and-policy) (mandatory) and
  declarative per-capability [scope entries](/tauri/scope-and-policy), both enforced before the
  backend touches DuckDB. See [Security overview](/tauri/security-overview).

## The command set at a glance

Every method on the JS `Database` class maps to exactly one Rust command
(`plugin:better-duck-tauri|<name>`). Parameters bind as **positional** `$1, $2, …` from a `values`
array.

| Command | JS method | Does | Reference |
| - | - | - | - |
| `load` / `close` | `Database.load` / `db.close` | Open / drop a connection | [Frontend overview](/tauri/frontend-overview) |
| `select` / `execute` | `db.select` / `db.execute` | Read query / write-DDL | [Query & execute](/tauri/query-and-execute) |
| `tables` / `columns` / `explain` | same | Schema introspection | [Schema introspection](/tauri/schema-introspection) |
| `import` / `export` | same (+ format helpers) | Parquet/CSV/JSON file I/O | [Import & export](/tauri/import-export) |
| `append_rows` | `db.appendRows` | Bulk-insert JSON rows | [Append rows](/tauri/append-rows) |
| `stream` / `interrupt` | `db.stream` / `db.interrupt` | Chunked streaming + cancel | [Streaming](/tauri/streaming) |
| `query_arrow` | `db.queryArrow` | Arrow IPC bytes (`arrow` feature) | [Arrow IPC](/tauri/arrow) |
| `load_extension` / `checkpoint` / `revert` | same | Extensions, WAL flush, undo migration | [Maintenance](/tauri/maintenance) |

## 30-second quickstart

Add the dependency (pick one backend feature) and register the plugin:

```toml theme={null}
# src-tauri/Cargo.toml
[dependencies]
better-duck-tauri = { version = "0.1.0-beta.8", features = ["backend-core"] }
```

```rust theme={null}
// src-tauri/src/main.rs
tauri::Builder::default()
    .plugin(better_duck_tauri::core::init()) // simplest; or ::diesel::init()
    .run(tauri::generate_context!())?;
```

Grant permissions in a capability file (the default set is read-only; writes and raw SQL are
opt-in):

```json theme={null}
{ "permissions": ["better-duck-tauri:default", "better-duck-tauri:allow-execute"] }
```

Drive it from the frontend:

```ts theme={null}
import Database from '@better-duck/tauri'

const db = await Database.load('duckdb:analytics.db') // or 'duckdb::memory:'
await db.execute('CREATE TABLE t (id INTEGER, name VARCHAR)')
await db.execute('INSERT INTO t VALUES ($1, $2)', [1, 'ada'])
const rows = await db.select('SELECT * FROM t WHERE id > $1', [0]) // [{ id: 1, name: 'ada' }]
await db.close()
```

See [Installation](/tauri/installation) and [Registration](/tauri/registration) for the full setup.

## See also

* [Installation](/tauri/installation) — the Rust dependency, feature flags, and the JS package.
* [Registration](/tauri/registration) — `tauri::Builder` wiring, simple and configured.
* [Security overview](/tauri/security-overview) — the untrusted-webview threat model.
* [Feature flags](/guide/feature-flags) — how `backend-core`, `backend-diesel`, and `arrow` relate
  to the rest of the workspace.


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