Skip to main content
Version: 0.31.1

Database Adapters

In this guide, you'll learn how to add support for new databases and new platforms to WatermelonDB.

Introduction​

WatermelonDB is designed to be database-agnostic. It's a frontend JavaScript database framework, but its high-level abstractions can be plugged in to any underlying database, platform, or UI framework. We call the translation layer between underlying databases and high-level WatermelonDB APIs database adapters.

Currently supported databases​

SQLite​

Supported frameworks:

  • React Native:
    • Operating systems:
      • iOS
      • Android
      • Windows (RNW New Architecture / WinAppSDK)
    • Implementations:
      • Nitro HybridObject (iOS, Android, and Windows)
  • NodeJS
    • via better-sqlite3 - contributed by Sid Ferreira

LokiJS​

Supported frameworks:

  • Web
    • Storage: IndexedDB
  • NodeJS
    • Storage: in-memory only

Why LokiJS? WebSQL would be a perfect fit for Watermelon, but sadly is a dead API, so we must use IndexedDB, but its querying capabilities make it unsuitable as a serious database. LokiJS implements a very fast in-memory querying API, using IndexedDB as storage.

Contribute these adapters!​

Please contribute to WatermelonDB. We'd love to support these platforms and databases:

Adding new React Native operating systems​

Thanks to our cross-platform C++ SQLite adapter, it takes very little code to add support for new React Native platforms (like macOS).

All you have to do is this:

  • Compile .cpp files in native/shared folder
  • Link library with sqlite3
    • Use system-provided sqlite3 if possible (we do that on iOS)
    • If not, we ship sqlite source in native/vendor/sqlite. Add that directory to search paths and compile sqlite3.c
  • Provide implementation for native/shared/DatabasePlatform.h
    • Please note that most of these functions can remain unimplemented (empty) for basic operation - e.g. you can skip logging, memory, turbo json support
  • Provide a React Native hook that calls Database::install(jsi::Runtime *)

Check out native/android and native/ios for two implementation examples. You might be able to reuse some code from these, e.g. platform support stubs or CMakeLists.txt.

Adding new frameworks to SQLite adapter​

Let's say you want to add support for a new JS+native framework, like Electron, Tauri, NativeScript or Capacitor.

This takes more work, but ultimately, given that (iOS, Android, JS, C++) are supported already (just for React Native and Node), you only need to develop the glue code necessary to bridge the gap between src/adapters/sqlite JS code, and the native but non-React-Native-specific bits. You'll need some familiarity with the platform you're trying to support, but little WatermelonDB/React Native/C++ familiary will be needed to get this done.

JS-side glue​

The general SQLite implementation is in src/adapters/sqlite/index.ts. It forwards database calls to this._dispatcher. The dispatcher is the JS-side bridge/glue code.

See src/adapters/sqlite/makeDispatcher to see concrete dispatchers and add your own, depending on the platform's convention of calling native code. For example:

  • makeDispatcher/index.ts (Node JS) just imports more JS code, since native=JS in this case
  • makeDispatcher/index.native.ts (React Native) uses the Nitromelon HybridObject on iOS, Android, and Windows.

Native-side glue​

Depending on the capabilities of the framework you want to support, there's a few ways to go about this:

The easy (JS-only) way. If your framework has existing SQLite bindings in JavaScript that work synchronously (similar to better-sqlite3 in Node), you can reuse code in src/adapters/sqlite/sqlite-node

The C++ way. Reuse native/shared and wrap it the way your framework talks to native code. On React Native that wrapper is the Nitromelon / NitromelonDatabase Nitro HybridObject (native/nitro, spec in src/nitro/Nitromelon.nitro.ts), including Windows (native/windows).

Adding new databases​

If you want to contribute support to new underlying databases (i.e. not SQL or LokiJS-based), this is a rough sketch of what's required:

  • A new FoodbAdapter that conforms to DatabaseAdapter (src/adapters/type.js). You can initially skip some method implementations for basic support, most basic are find, query, count, batch.
  • Some way to convert WatermelonDB's query language into queries specific for your database. For reference, see:
    • src/adapters/sqlite/encodeQuery for generating SQL
    • src/adapters/lokijs/worker/encodeQuery for generating LokiJS queries + executeQuery which executes joins (which Loki does not natively support)