Skip to main content

Nitro Modules · SQLite · C++ / Swift / Kotlin

Offline-first SQLite for React Native, synced entirely in native code

Offline-first SQLite for React Native with a 100% native sync engine.

query.ts
Database.select(UserSchema)
.where(and(eq('id', 1), like('email', '%@company.com')))
.orderBy('updatedAt', 'desc')
.limit(50)
.execute();

// every write here queues automatically for the native sync engine
Database.insert(UserSchema)
.values({ id: 2, name: 'Ada', email: 'ada@co.com', updatedAt: Date.now() })
.execute();

Everything a background sync engine should be, none of the JS baggage

Sync runs 100% natively

The sync orchestrator, HTTP client, credential provider, and background scheduler live entirely in C++/Swift/Kotlin. No JS bundle, no JS thread, no headless task required.

Declarative schemas

Tables, indexes, relations, and sync contracts are plain TypeScript data, interpreted natively. No SQL to write, no codegen step for schema changes.

Automatic sync queue

Every INSERT/UPDATE/DELETE — including raw SQL — is captured by a SQLite trigger and queued for sync. You never call enqueue yourself.

Typed query builder

Drizzle-style select/insert/update/delete/transaction, fully typed from your schema via InferSelectModel/InferInsertModel.

Reactive hooks

useQuery and useInfiniteQuery subscribe to table changes and re-run automatically, no matter whether the write came from your code or the sync engine.

OAuth2 out of the box

Access/refresh tokens stored in Keychain (iOS) / Keystore (Android), refreshed natively — no token juggling in JS.

Under the hood

The sync engine never wakes the JS runtime

A background job wakes the native sync orchestrator directly — your app doesn't need to be open, and no JS thread ever spins up for it.

TypeScript (DX layer)
JSI (Nitro Modules) — reactive change events flow back
Native Core (C++)
  • SQLite + LRU statement cache
  • Migration Engine (ADD COLUMN)
  • Trigger Engine → sync_queue
  • Sync Orchestrator
  • Credential Provider (OAuth2)
  • HTTP Client
platform:: function contracts
Swift (iOS) / Kotlin (Android) shims
  • BGTaskScheduler / WorkManager — background scheduler
  • NWPathMonitor / ConnectivityManager — network monitor
  • Keychain / Keystore — secure token storage
Your REST API

Salve DB Studio

Browse and edit your running app's database, live

A local, live-connected UI — Prisma/Drizzle Studio style — for the SQLite database inside your running app. No extra setup: your app auto-connects over WebSocket the moment you call Database.configure(...) in development.

  • Browse every table, including internal sync-engine tables
  • Insert, edit, and delete rows against the live device
  • Run raw SQL against the running database
  • Multiple devices/simulators, one device selector
Learn how to use Studio →
Salve DB Studio

Ready to go offline-first?

Declare a schema, wrap your app in SalveDbProvider, and you have typed queries, reactive hooks, and native background sync in minutes.