Open-source project
Nozbe/WatermelonDB avatar
Nozbe/WatermelonDB

WatermelonDB: A Lazy, Reactive SQLite Layer for React Native Apps

🍉 Reactive & asynchronous database for powerful React and React Native apps ⚡️

11,790 stars662 forksJavaScriptMIT

At a glance

What is it?
WatermelonDB keeps large local datasets out of JavaScript memory by querying SQLite on a native thread and wiring results into React components. It is a fit for offline-first apps with thousands of records, and a poor fit for small apps that Redux with a persistence adapter already handles.
Who is it for?
Adopt WatermelonDB if your React Native app stores thousands of records locally, needs instant launch, and you are prepared to write your own sync backend, because the project ships no server. Do not adopt it for a small app that Redux or MobX with a persistence adapter already handles, and do not adopt it expecting a managed cloud service.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What WatermelonDB Solves for React Native Data Loads

The problem is launch time. The README states plainly that loading a full database into JavaScript is expensive, and that once an app scales to thousands or tens of thousands of records, a Redux or MobX store with a persistence adapter makes the app slow to start, especially on slower Android devices. WatermelonDB's answer is to be lazy: nothing is loaded until it is requested, and all querying runs against SQLite on a separate native thread. That is a different architecture from holding the working set in JS memory and rehydrating it at boot.

The audience follows from that. This is for teams building complex React Native apps where the data is relational and the device is offline part of the time. The README points to Nozbe itself, running on WatermelonDB since 2017, plus CAPMO, Mattermost, Rocket.Chat, Steady, Aerobotics, SportsRecruits, Todorant and others. If your app is a form over a remote API with a dozen cached rows, the lazy machinery buys you nothing and costs you a schema, a migration system and a sync design.

How Lazy Loading and withObservables Work Together

Two mechanisms sit at the core. First, records are not materialized until a query asks for them, and the query itself is executed by SQLite on a native thread rather than in JavaScript. Second, the results are observable. The README describes the second half with a to-do example: completing a task re-renders the task component, the list (to reorder), and the relevant counters.

The React binding is withObservables. You declare which props a component depends on, and the returned component re-renders when those records change, wherever in the app the change happened. Models are declared as classes with decorators: @field for columns, @children for relations. The README's example defines Post with name and body fields and a comments child collection, and Comment with body and author.

Note what this means in practice. The observable layer is optional in the sense that a JS API exists for other UI frameworks, but the reactive behaviour is the reason most people pick this over raw SQLite. Raw SQLite gives you speed without change propagation; WatermelonDB gives you both, at the cost of defining models and keeping them in step with the database schema.

Installing WatermelonDB and Rendering a First Reactive List

The package is published as @nozbe/watermelondb on npm, and package.json sets an engine floor of Node 18 or newer. The README does not include a full install walkthrough, so treat the repository's own docs site as the authority for platform setup. The npm package name is the one confirmed by package.json.

bash
yarn add @nozbe/watermelondb

After that, define a model. This is the README's Post example, using the @field and @children decorators.

js
class Post extends Model {
  @field('name') name
  @field('body') body
  @children('comments') comments
}

Then connect a component to the data with withObservables. The README's Comment component reads comment.body and comment.author, and the enhancer declares that it depends on the comment prop.

js
const enhance = withObservables(['comment'], ({ comment }) => ({
  comment,
}))
const EnhancedComment = enhance(Comment)

Render the parent with both the post and its comments, and the tree updates itself when either changes.

js
const enhance = withObservables(['post'], ({ post }) => ({
  post,
  comments: post.comments
}))

What you should see is a fully reactive tree: add, change or remove a post or comment and the affected components re-render without manual wiring. Native platform setup (iOS, Android, Windows) is not spelled out in the README, so follow the docs site for pod install and Gradle steps before expecting the example to run.

Where WatermelonDB Is the Wrong Choice

The clearest limitation is sync. WatermelonDB is offline-first, but the README says you sync with your own backend. There is no hosted service, no protocol server and no account system in the package. If your team cannot build and operate a sync endpoint that understands WatermelonDB's change tracking, you have adopted half a system.

The second limitation is scope. The README's own framing is that for simple apps, Redux or MobX with a persistence adapter is the easiest way to go. That is not marketing hedging; it is an accurate statement of where the lazy-loading architecture stops paying for itself. You take on model definitions, a schema, migrations and a native build for platforms that each need their own module.

Third, platform coverage is not uniform. The README lists iOS, Android, Windows, web and Node.js, but the repository has separate native directories and separate test scripts for Android, iOS and Windows, which tells you the native surface is maintained per platform rather than once. Expo users in particular should verify current support rather than assume it.

Finally, maintenance signals matter. The repository is not archived, and the last push was on 2026-09-16, which is recent. There is a CHANGELOG-Unreleased.md at the top level, so unreleased changes accumulate in the repository before a release is cut. The README does not document rollback for migrations, so plan schema changes with that silence in mind.

WatermelonDB vs SQLite, RxDB and Realm

Against plain SQLite: SQLite is the storage engine underneath. Using it directly means you write your own change notification, your own model layer and your own React glue. WatermelonDB adds exactly those three things on top of the same foundation. If your app has no reactive UI requirement and no relational model, direct SQLite is less machinery.

Against RxDB: both are reactive and offline-capable, but the storage story differs. WatermelonDB is built on SQLite and executes queries on a native thread, which is the mechanism behind its launch-time claim. RxDB's reactive layer is built around its own storage adapters and replication plugins. If you want replication handled by the library rather than by your own backend, that difference is the deciding one, and WatermelonDB's README explicitly leaves sync to you.

Against Realm: Realm is an object database with its own engine and its own sync product. WatermelonDB is relational and SQLite-backed, with a JS API and optional RxJS observables. The trade is between a managed object store and a relational layer where you own the server side.

Against Expo SQLite: that is the platform's own SQLite binding. It gives you a database but not the observable model layer or the lazy React integration. WatermelonDB is the higher-level choice when reactivity is the requirement.

Licence, Maintenance and Upgrade Cost

WatermelonDB is MIT licensed, per the LICENSE file and the badge in the README. MIT is permissive: you can use it commercially and in closed-source apps, provided the copyright notice and permission notice are preserved. That is a description of the licence text, not legal advice; have your own counsel review distribution obligations if you are unsure.

The practical upgrade cost sits in two places. First, the native modules: the repository carries native/ directories with Android, iOS and Windows test projects, plus a WatermelonDB.podspec and a react-native.config.js, so upgrading can mean rebuilding native dependencies, not just bumping an npm version. The cocoapods script in package.json updates hermes-engine and reinstalls pods, which hints at how coupled the native side is to the React Native toolchain.

Second, the schema. Because the README does not document rollback, an upgrade that changes your schema is a forward-only operation as far as the documentation is concerned. The repository keeps CHANGELOG.md and CHANGELOG-Unreleased.md, so read both before upgrading, and check the engine floor in package.json (currently Node 18 or newer) against your CI image.

Editorial conclusion

Adopt WatermelonDB if your React Native app stores thousands of records locally, needs instant launch, and you are prepared to write your own sync backend, because the project ships no server. Do not adopt it for a small app that Redux or MobX with a persistence adapter already handles, and do not adopt it expecting a managed cloud service. Before committing, verify that your target platforms are covered by the native modules in the repository, that your toolchain satisfies the Node 18 engine floor, and that your schema migration plan accounts for the fact that the README does not document rollback.

Frequently asked questions

What is WatermelonDB?

It is a reactive, offline-first database framework for React and React Native apps, built on SQLite. It loads records lazily and runs queries on a native thread, and it can expose data to components through an optional RxJS-based observable API.

How do I use WatermelonDB in a React Native app?

Install the @nozbe/watermelondb package, define models with the @field and @children decorators, and wrap components with withObservables so they re-render when the records they depend on change. The README's Post and Comment example shows the full pattern.

Is WatermelonDB free?

Yes. The project is MIT licensed, per the LICENSE file and the badge in the README, which permits commercial and closed-source use as long as the copyright and permission notice are preserved.

How does WatermelonDB compare with using SQLite directly?

SQLite is the storage engine WatermelonDB is built on, but using it directly leaves you to write the model layer, change notification and React integration yourself. WatermelonDB adds lazy loading, a native-thread query path and an observable layer on top of the same foundation.

What is WatermelonDB?

It is a reactive database framework for React and React Native that stores data in SQLite and exposes it to components through an observable API, so changes propagate to the UI automatically.

Official sources

  1. Issues
  2. License: MIT
  3. Nozbe/WatermelonDB on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nozbe-watermelondb.svg)](https://hysenlabs.com/projects/nozbe-watermelondb)