First, add Watermelon to your project:

yarn add @nozbe/watermelondb
yarn add @nozbe/with-observables

or alternatively if you prefer npm:

npm install @nozbe/watermelondb
npm install @nozbe/with-observables

React Native setup

  1. Install the Babel plugin for decorators if you haven't already:

    yarn add --dev @babel/plugin-proposal-decorators


    npm install -D @babel/plugin-proposal-decorators
  2. Add ES6 decorators support to your .babelrc file:

      "presets": ["module:metro-react-native-babel-preset"],
      "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }]
  3. Set up your iOS or Android project — see instructions below

iOS (React Native)

  1. Set up Babel config in your project

    See instructions above ⬆️

  2. Add Swift support to your Xcode project:

    • Open ios/YourAppName.xcodeproj in Xcode
    • Right-click on Your App Name in the Project Navigator on the left, and click New File…
    • Create a single empty Swift file to the project (make sure that Your App Name target is selected when adding), and when Xcode asks, press Create Bridging Header and do not remove Swift file then.
  3. Link WatermelonDB's native library with the Xcode project:

    You can link WatermelonDB manually or using CocoaPods:

    • Manually

      1. Open your project in Xcode, right click on Libraries in the Project Navigator on the left and click Add Files to "Your Project Name". Look under node_modules/@nozbe/watermelondb/native/ios and select WatermelonDB.xcodeproj
      2. Go to Project settings (top item in the Project navigator on the left), select your app name under TargetsBuild PhasesLink Binary With Libraries, and add libWatermelonDB.a

      For more information about linking libraries manually, see React Native documentation.

    • Link WatermelonDB's native library with the Xcode project -- using CocoaPods:

      1. Add this to your CocoaPods (might not be needed if you're using autolinking):

        pod 'WatermelonDB', :path => '../node_modules/@nozbe/watermelondb'
      2. Unfortunately, the build will fail due to an issue with React Native's Pods, so you need to modify this line:

        # Before:
        pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
        # Change to:
        pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi', :modular_headers => true

    Note that Xcode 9.4 and a deployment target of at least iOS 9.0 is required (although Xcode 11.5+ and iOS 12.0+ are recommended).

Android (React Native)

  1. Set up Babel config in your project

    See instructions above ⬆️

  2. In android/settings.gradle, add:

    include ':watermelondb'
    project(':watermelondb').projectDir =
        new File(rootProject.projectDir, '../node_modules/@nozbe/watermelondb/native/android')
  3. In android/app/build.gradle, add:

    apply plugin: ""
    apply plugin: 'kotlin-android'  // ⬅️ This!
    // ...
    dependencies {
        // ...
        implementation project(':watermelondb')  // ⬅️ This!
  4. In android/build.gradle, add Kotlin support to the project:

    buildscript {
        ext.kotlin_version = '1.3.21'
        // ...
        dependencies {
            // ...
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  5. And finally, in android/app/src/main/java/{YOUR_APP_PACKAGE}/, add:

    // ...
    import com.nozbe.watermelondb.WatermelonDBPackage; // ⬅️ This!
    // ...
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new WatermelonDBPackage() // ⬅️ Here!
  6. Troubleshooting. If you get this error:

    Can't find variable: Symbol

    You might need a polyfill for ES6 Symbol:

    yarn add es6-symbol

    And in your index.js:

    import 'es6-symbol/implement'

    Alternatively, we also recommend jsc-android, with which you don't need this polyfill, and it also makes your app faster.

NodeJS setup

  1. Install better-sqlite3 peer dependency

    yarn add --dev better-sqlite3


    npm install -D better-sqlite3

Web setup

This guide assumes you use Webpack as your bundler.

  1. If you haven't already, install Babel plugins for decorators, static class properties, and async/await to get the most out of Watermelon. This assumes you use Babel 7 and already support ES6 syntax.
    yarn add --dev @babel/plugin-proposal-decorators
    yarn add --dev @babel/plugin-proposal-class-properties
    yarn add --dev @babel/plugin-transform-runtime
    npm install -D @babel/plugin-proposal-decorators
    npm install -D @babel/plugin-proposal-class-properties
    npm install -D @babel/plugin-transform-runtime
  2. Add ES7 support to your .babelrc file:
      "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }],
             "helpers": true,
             "regenerator": true

If you want to use Web Worker for WatermelonDB (this has pros and cons, we recommend you start without Web Workers, and evaluate later if it makes sense for your app to use them):

  1. Install worker-loader Webpack plugin to add support for Web Workers to your app:

    yarn add --dev worker-loader


    npm install -D worker-loader
  2. And add this to Webpack configuration:

    // webpack.config.js
      module: {
        rules: [
          // ⬇️ Add this:
            test: /\.worker\.js$/,
            use: { loader: 'worker-loader' }
      // ...
      output: {
        // ...
        globalObject: 'this', // ⬅️ And this

Set up Database

Create model/schema.js in your project:

import { appSchema, tableSchema } from '@nozbe/watermelondb'

export default appSchema({
  version: 1,
  tables: [
    // tableSchemas go here...

You'll need it for the next step. Now, in your index.js:

import { Database } from '@nozbe/watermelondb'
import SQLiteAdapter from '@nozbe/watermelondb/adapters/sqlite'

import schema from './model/schema'
// import Post from './model/Post' // ⬅️ You'll import your Models here

// First, create the adapter to the underlying database:
const adapter = new SQLiteAdapter({
  // optional database name or file system path
  // dbName: 'myapp',
  // optional migrations
  // migrations,
  // synchronous mode only works on iOS. improves performance and reduces glitches in most cases, but also has some downsides - test with and without it
  synchronous: true,
  // experimental JSI mode, a more advanced version of synchronous: true
  // experimentalUseJSI: true,
  // Optional, but you should implement this method:
  onSetUpError: error => {
    // Database failed to load -- offer the user to reload the app or log out

// Then, make a Watermelon database from it!
const database = new Database({
  modelClasses: [
    // Post, // ⬅️ You'll add Models to Watermelon here
  actionsEnabled: true,

The above will work on React Native (iOS/Android) and NodeJS. For the web, instead of SQLiteAdapter use LokiJSAdapter:

import LokiJSAdapter from '@nozbe/watermelondb/adapters/lokijs'

const adapter = new LokiJSAdapter({
  // migrations, // optional migrations
  useWebWorker: false, // recommended setting for new projects
  useIncrementalIndexedDB: true, // recommended for new projects. improves performance (but incompatible with early Watermelon databases)
  // dbName: 'myapp', // optional db name
  // Optional, but recommended event handlers:
  onIndexedDBVersionChange: () => {
    // database was deleted in another browser tab (user logged out), so we must make sure we delete
    // it in this tab as well
    if (checkIfUserIsLoggedIn()) {
  onQuotaExceededError: (error) => {
    // Browser ran out of disk space -- do something about it
  onSetUpError: (error) => {
    // Database failed to load -- offer the user to reload the app or log out

// The rest is the same!

Next steps

➡️ After Watermelon is installed, define your app's schema