@walkthru-earth/react-native-duckdb
v0.1.5
Published
High-performance native DuckDB bindings for React Native using Nitro Modules
Downloads
1,110
Readme
@walkthru-earth/react-native-duckdb
High-performance native DuckDB bindings for React Native using Nitro Modules.
Features
- Native DuckDB integration (not WASM)
- High performance via JSI bindings
- Full SQL support including:
- SELECT, INSERT, UPDATE, DELETE
- Prepared statements with parameter binding
- Transactions
- Extensions (parquet, json, httpfs, etc.)
- Supports iOS and Android
- TypeScript first API
Requirements
| Platform | Minimum Version | | ------------ | ------------------------ | | iOS | 13.4+ | | Android | API 24+ (Android 7.0) | | React Native | 0.76+ (New Architecture) |
Supported Architectures
| Platform | Architectures |
| -------- | ------------------------------------------------ |
| iOS | arm64 (device), arm64 + x86_64 (simulator) |
| Android | arm64-v8a, armeabi-v7a, x86_64 |
Installation
npm install @walkthru-earth/react-native-duckdb react-native-nitro-modules
# or
yarn add @walkthru-earth/react-native-duckdb react-native-nitro-modules
# or
bun add @walkthru-earth/react-native-duckdb react-native-nitro-modulesiOS
cd ios && pod installAndroid
No additional setup required. The package includes pre-built native libraries for the following architectures:
arm64-v8a(64-bit ARM, most modern devices)armeabi-v7a(32-bit ARM, older devices)x86_64(64-bit x86, emulators)
Your app's android/app/build.gradle should include the architectures you want to support:
android {
defaultConfig {
ndk {
abiFilters "armeabi-v7a", "x86_64", "arm64-v8a"
}
}
}Usage
Basic Usage
import { duckdb, parseQueryResult } from 'react-native-duckdb'
// Open an in-memory database
const db = duckdb.openInMemory()
// Execute SQL
await db.execute('CREATE TABLE users (id INTEGER, name VARCHAR)')
await db.execute("INSERT INTO users VALUES (1, 'Alice'), (2, 'Bob')")
// Query data
const result = await db.execute('SELECT * FROM users')
const { rows } = parseQueryResult(result)
console.log(rows) // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }]
// Close when done
db.close()File-based Database
import { duckdb } from 'react-native-duckdb'
import { DocumentDirectoryPath } from 'react-native-fs'
const dbPath = `${DocumentDirectoryPath}/mydata.duckdb`
const db = duckdb.open(dbPath)
// Your database will persist between app restartsPrepared Statements
const stmt = db.prepare('SELECT * FROM users WHERE id = ?')
stmt.bindNumber(1, 1)
const result = await stmt.execute()
// Reuse with different parameters
stmt.reset()
stmt.bindNumber(1, 2)
const result2 = await stmt.execute()
stmt.close()Transactions
await db.beginTransaction()
try {
await db.execute('INSERT INTO users VALUES (3, "Charlie")')
await db.execute('UPDATE stats SET user_count = user_count + 1')
await db.commit()
} catch (error) {
await db.rollback()
throw error
}Load Extensions
// Load a pre-built extension
await db.loadExtension('parquet')
// Query parquet files directly
const result = await db.execute("SELECT * FROM 'data.parquet'")Database Options
const db = duckdb.open('/path/to/db.duckdb', {
readOnly: true,
threads: 4,
maxMemory: '2GB',
})API Reference
duckdb
Main module with factory methods:
duckdb.version- DuckDB library versionduckdb.platform- Current platform ('ios' or 'android')duckdb.open(path, options?)- Open a file-based databaseduckdb.openInMemory(options?)- Open an in-memory database
Database
Database connection methods:
execute(sql)- Execute SQL asynchronouslyexecuteSync(sql)- Execute SQL synchronouslyprepare(sql)- Create a prepared statementbeginTransaction()/commit()/rollback()- Transaction controlloadExtension(name)/installExtension(name)- Extension managementclose()- Close the connection
PreparedStatement
Prepared statement methods:
bindString(index, value)- Bind a string parameterbindNumber(index, value)- Bind a number parameterbindBoolean(index, value)- Bind a boolean parameterbindBigInt(index, value)- Bind a bigint parameterbindBlob(index, value)- Bind an ArrayBuffer parameterbindNull(index)- Bind nullexecute()/executeSync()- Execute the statementreset()- Clear bindings for reuseclose()- Deallocate the statement
parseQueryResult(result)
Helper function to parse QueryResult into a more usable format with typed row objects.
Extension Constants
import {
EXTENSIONS,
EXTENSION_TESTS,
DEMO_PARQUET_URL,
} from 'react-native-duckdb'
// Available extension names
console.log(EXTENSIONS.json) // 'json'
console.log(EXTENSIONS.parquet) // 'parquet'
// Test queries for E2E testing
console.log(EXTENSION_TESTS.json) // SELECT json_extract...
// Demo parquet file for httpfs testing
console.log(DEMO_PARQUET_URL) // https://duckdb.org/data/holdings.parquetPre-built Extensions
The following extensions are pre-built and included:
| Extension | Description | Android | iOS |
| ------------------ | ------------------------------------ | :-----: | :-: |
| icu | International Components for Unicode | ✅ | ✅ |
| json | JSON functions | ✅ | ✅ |
| parquet | Parquet file support | ✅ | ✅ |
| httpfs | HTTP/S3 file system | ✅ | ✅ |
| fts | Full-text search | ✅ | ✅ |
| inet | Network address functions | ✅ | ✅ |
| vss | Vector similarity search | ✅ | ✅ |
| autocomplete | Query autocomplete | ✅ | ✅ |
| sqlite_scanner | SQLite file scanner | ✅ | ✅ |
| h3 | H3 hexagonal geospatial indexing | ✅ | ✅ |
| postgres_scanner | PostgreSQL connector | ❌ | ✅ |
Development
Building from Source
This project uses pre-built DuckDB libraries from duckdb-dart.
# Install dependencies
bun install
# Generate Nitro specs
bun run specs
# TypeCheck
bun run typecheckTesting
# Run unit tests
bun run test
# Run tests with coverage
bun run test:coveragePre-commit Hooks
This project uses Husky + lint-staged for pre-commit hooks:
- ESLint + Prettier on staged TypeScript files
- All tests run before each commit
License
MIT
Credits
- DuckDB - The database engine
- Nitro Modules - High-performance React Native bindings
- duckdb-dart - DuckDB Dart bindings with pre-built native library workflows
