
A minimal DuckDB WASM binding for browsers and Cloudflare Workers.
| Package | Environment | API Style |
|---|---|---|
| @ducklings/browser | Browsers | Asynchronous (Web Worker) |
| @ducklings/workers | Cloudflare Workers with Iceberg* | Asynchronous (Asyncify) |
| @ducklings/workers-ducklake | Cloudflare Workers with DuckLake* | Asynchronous (Asyncify) |
All packages provide the same async API, but use different mechanisms and bundled extensions under the hood.
*The workers packages require a Cloudflare Workers Paid Plan because the bundled WASM is close to Cloudflare's compressed Worker size limit. Use
wrangler deploy --dry-run --outdir bundledto verify the final gzip size.
# For browsers
npm install @ducklings/browser
# For Cloudflare Workers
npm install @ducklings/workers
# For Cloudflare Workers with DuckLake
npm install @ducklings/workers-ducklake
import { init, DuckDB } from '@ducklings/browser';
// Initialize the WASM module (runs in Web Worker)
await init();
// Create database and connection
const db = new DuckDB();
const conn = await db.connect();
// Execute queries (async)
const rows = await conn.query('SELECT 42 as answer');
console.log(rows); // [{ answer: 42 }]
// Clean up
await conn.close();
await db.close();
import { init, DuckDB } from '@ducklings/workers';
import wasmModule from '@ducklings/workers/wasm';
// Initialize with pre-compiled WASM module
await init({ wasmModule });
// Create database and connection
const db = new DuckDB();
const conn = db.connect();
// Execute queries (async)
const rows = await conn.query('SELECT 42 as answer');
console.log(rows); // [{ answer: 42 }]
// Clean up
conn.close();
db.close();
Both packages expose the same async API:
// Works in both packages
const rows = await conn.query('SELECT * FROM range(10)');
const table = await conn.queryArrow('SELECT * FROM range(10)');
const affected = await conn.execute('INSERT INTO t VALUES (1)');
const results = await stmt.run();
json extension