Installation
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
-
Install the Babel plugin for decorators if you haven't already:
yarn add --dev @babel/plugin-proposal-decorators
or
npm install -D @babel/plugin-proposal-decorators
-
Add ES6 decorators support to your
.babelrc
file:{ "presets": ["module:metro-react-native-babel-preset"], "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }] ] }
-
Set up your iOS or Android project — see instructions below
iOS (React Native)
-
Set up Babel config in your project
See instructions above ⬆️
-
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 removeSwift
file then.
- Open
-
Link WatermelonDB's native library with the Xcode project:
You can link WatermelonDB manually or using CocoaPods:
-
Manually
- 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 selectWatermelonDB.xcodeproj
- Go to Project settings (top item in the Project navigator on the left), select your app name under Targets → Build Phases → Link Binary With Libraries, and add
libWatermelonDB.a
For more information about linking libraries manually, see React Native documentation.
- 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
-
Link WatermelonDB's native library with the Xcode project -- using CocoaPods:
-
Add this to your CocoaPods (might not be needed if you're using autolinking):
pod 'WatermelonDB', :path => '../node_modules/@nozbe/watermelondb'
-
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)
-
Set up Babel config in your project
See instructions above ⬆️
-
In
android/settings.gradle
, add:include ':watermelondb' project(':watermelondb').projectDir = new File(rootProject.projectDir, '../node_modules/@nozbe/watermelondb/native/android')
-
In
android/app/build.gradle
, add:apply plugin: "com.android.application" apply plugin: 'kotlin-android' // ⬅️ This! // ... dependencies { // ... implementation project(':watermelondb') // ⬅️ This! }
-
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" } }
-
And finally, in
android/app/src/main/java/{YOUR_APP_PACKAGE}/MainApplication.java
, add:// ... import com.nozbe.watermelondb.WatermelonDBPackage; // ⬅️ This! // ... @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new WatermelonDBPackage() // ⬅️ Here! ); }
-
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
-
Install better-sqlite3 peer dependency
yarn add --dev better-sqlite3
or
npm install -D better-sqlite3
Web setup
This guide assumes you use Webpack as your bundler.
- 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.
oryarn 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
- Add ES7 support to your
.babelrc
file:{ "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties", { "loose": true }], [ "@babel/plugin-transform-runtime", { "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):
-
Install worker-loader Webpack plugin to add support for Web Workers to your app:
yarn add --dev worker-loader
or
npm install -D worker-loader
-
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({
schema,
// dbName: 'myapp', // optional database name or file system path
// migrations, // optional migrations
synchronous: true, // synchronous mode only works on iOS. improves performance and reduces glitches in most cases, but also has some downsides - test with and without it
// experimentalUseJSI: true, // experimental JSI mode, use only if you're brave
})
// Then, make a Watermelon database from it!
const database = new Database({
adapter,
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({
schema,
// migrations, // optional migrations
useWebWorker: false, // recommended for new projects. tends to improve performance and reduce glitches in most cases, but also has downsides - test with and without it
useIncrementalIndexedDB: true, // recommended for new projects. improves performance (but incompatible with early Watermelon databases)
// dbName: 'myapp', // optional db name
// It's recommended you implement this method:
// 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()) {
// window.location.reload()
// }
// },
// Optional:
// onQuotaExceededError: (error) => { /* do something when user runs out of disk space */ },
})
// The rest is the same!
Next steps
➡️ After Watermelon is installed, define your app's schema