Adapters — SQLite Expo (React Native)

Use the SQLite Expo adapter to run SQLite on-device in Expo/React Native apps. It persists by default and exposes the same vibecode‑db client API you use everywhere else—only the storage changes.

Execution rule: In v1.0, .select(projection) executes the query — chain filters/modifiers before calling it. Writes (insert, update, delete) execute immediately.


When to use

  • Offline‑first mobile apps
  • Low‑latency reads/writes with local persistence
  • Hybrid sync patterns (local first, cloud later)

Installation

1pnpm add @vibecode-db/client @vibecode-db/sqlite-expo
2# or: npm i ... | yarn add ...

@vibecode-db/sqlite-expo depends on @vibecode-db/sqlite-core, which depends on @vibecode-db/client. You don’t import sqlite-core directly.


Minimal wiring

1// db/client.expo.ts
2import { createClient } from '@vibecode-db/client'
3import { SQLiteExpoAdapter } from '@vibecode-db/sqlite-expo'
4import { db } from './schema' // your defineSchema(...)
5
6export const vibecode = createClient({
7  dbSpec: {
8    schema: db.zodBundle,
9    relations: db.relations,   // recommended for relation-aware projections
10    // seed?: { ... }           // optional boot data (adapter policy-dependent)
11    // meta?: { ... }           // optional adapter-specific metadata
12  },
13  adapter: (ctx) => new SQLiteExpoAdapter(ctx, {
14    dbName: 'vibecode.db',
15    resetOnStart: false,       // persists by default; set true to wipe on app start (dev)
16  }),
17})

Adapter options

OptionTypePurpose
dbNamestringOn‑device database filename (e.g., vibecode.db).
resetOnStartbooleanStart with a clean DB on app launch (useful for dev/test). Defaults to false.

Relational reads — current SQLite limits

SQLite adapters implement “SELECT list + LEFT JOINs for one‑level many‑to‑one nesting.”

  • todos → users(name) works via .select('id, title, users(name)')
  • ❌ Deep chains (a → b → c) and inline 1→M expansions aren’t executed today — use two queries or DB‑side views.

Example: first query

1// one-level M→1 nested projection
2const todos = await vibecode
3  .from('todos')
4  .where({ user_id: 1 })
5  .order('created_at', { ascending: false })
6  .limit(10)
7  .select('id, title, users(name)')

Persistence & seeding

  • Persistence: on-device by default (via Expo’s SQLite under the hood). Toggle resetOnStart during development to wipe data each run.
  • Seeding: optional dbSpec.seed may be applied by policy (commonly insert‑if‑empty on first run). Manage schema via your SQLite migrations (SQL DDL).

Summary

SQLite Expo gives mobile apps fast, local, persistent data with the same fluent query surface you use on Web and Supabase. Keep your schema/types identical, and swap adapters without touching your UI queries.