Skip to main content
Version: 0.30.0-beta.8

NitromelonDB

ℹ️ NitromelonDB is a fork of WatermelonDB

WatermelonDB (@nozbe/watermelondb) has not been updated in a while. React Native, iOS, and Android keep moving — New Architecture, yearly OS releases, new JS runtimes — and a reactive database that sits on native SQLite has to move with them.

NitromelonDB continues that work. Same lazy, observable, SQLite-backed model you already know; a codebase we can keep evolving.

Why this fork exists

  • Upstream is quiet. Apps still need the library to track frequent React Native, iOS, and Android version changes.
  • New Architecture only. Native SQLite on iOS, Android, and Windows (RNW 0.84 / WinAppSDK) goes through Nitro Modules. The old React Native architecture (Paper / the legacy bridge) is not supported.
  • First-class Expo. A config plugin covers development builds, EAS Build, and EAS Update. It replaces @morrowdigital/watermelondb-expo-plugin. Expo Go is not supported.
  • One TypeScript codebase. Implementation lives in TypeScript under strict checking. That removes Flow and the standalone .d.ts layer, so types and runtime cannot drift.
  • Simpler native install. SQLite and simdjson are vendored in-tree. No FMDB, no @nozbe/sqlite / @nozbe/simdjson, no separate android-jsi package. Autolinking is enough.
  • Current platforms. Tested on React Native 0.83+ (NotesApp is Expo SDK 57 / RN 0.86) and React 19. Android builds with 16kB page alignment. Electron can run SQLite in the main process via RemoteAdapter.
  • Extensively tested — a safer bet. Every push runs the full stack in CI, not just JS unit tests: the shared correctness suite (CRUD, queries, migrations, concurrent writers, batches) executes against the real native SQLite bridge on real iOS and Android devices, and the Expo NotesApp ships Maestro end-to-end flows — cold start, create/pin/delete, kill-and-relaunch persistence, sticky Q.skip / Q.take pagination — run on iOS, Android, and Windows.
  • Observability. Nested writers, stuck readers, and incorrect callWriter/callReader usage should fail loudly so engineers can see where — not hang in production. See Observability.
  • Performance. We want to keep improving SQLite, native, and JS performance. The TypeScript rewrite is one step on that path (including future runtimes such as Static Hermes), alongside further native optimizations.
  • Same product, new package name. Install nitromelondb and import from nitromelondb (not @nozbe/watermelondb). Existing SQLite files, schema, and models keep working. Step-by-step: Migrating from WatermelonDB.

On the roadmap: SQLCipher (including existing databases), VACUUM, macOS, wa-sqlite on the web, paginated sync, more reliable migrations, and clearer critical-error handling.

yarn add nitromelondb
# or: npm install nitromelondb

On Expo, add "nitromelondb" to the plugins array in app.json (development builds, EAS Build, and EAS Update). See Installation.

import { Database } from 'nitromelondb'
import SQLiteAdapter from 'nitromelondb/adapters/sqlite'

Full credit to @Nozbe and Radek Pietruszewski for designing and shipping the original WatermelonDB.

➡️ Learn more: see full documentation

NitromelonDB — a reactive database framework

Build powerful React and React Native apps that scale from hundreds to tens of thousands of records and remain fast ⚡️

MIT LicensenpmDiscord

NitromelonDB
⚡️Launch your app instantly no matter how much data you have
📈Highly scalable from hundreds to tens of thousands of records
😎Lazy loaded. Only load data when you need it
🔄Offline-first. Sync with your own backend
📱Multiplatform. iOS, Android, Windows, web, Node.js, and Expo (EAS Build and EAS Update)
🧪Extensively tested. Native bridge tests + Maestro e2e run on real iOS, Android, and Windows every push
⚛️Optimized for React. Easily plug data into components
🧰Framework-agnostic. Use JS API to plug into other UI frameworks
Fast. And getting faster with every release!
Proven. Powers Nozbe since 2017 (and many others)
Reactive. (Optional) RxJS API
🔗Relational. Built on rock-solid SQLite foundation
⚠️Static typing with TypeScript

Why Watermelon?

WatermelonDB (and this fork) is a different way of dealing with user data in React Native and React web apps.

It's optimized for building complex applications in React Native, and the number one goal is real-world performance. In simple words, your app must launch fast.

For simple apps, using Redux or MobX with a persistence adapter is the easiest way to go. But when you start scaling to thousands or tens of thousands of database records, your app will now be slow to launch (especially on slower Android devices). Loading a full database into JavaScript is expensive!

Watermelon fixes it by being lazy. Nothing is loaded until it's requested. And since all querying is performed directly on the rock-solid SQLite database on a separate native thread, most queries resolve in an instant.

But unlike using SQLite directly, Watermelon is fully observable. So whenever you change a record, all UI that depends on it will automatically re-render. For example, completing a task in a to-do app will re-render the task component, the list (to reorder), and all relevant task counters. Learn more.

React Native EU: Next-generation React Databases

📺 Next-generation React databases
(a talk about WatermelonDB)

Usage

Quick (over-simplified) example: an app with posts and comments.

First, you define Models:

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

class Comment extends Model {
@field('body') body
@field('author') author
}

Then, you connect components to the data:

const Comment = ({ comment }) => (
<View style={styles.commentBox}>
<Text>{comment.body} — by {comment.author}</Text>
</View>
)

// This is how you make your app reactive! ✨
const enhance = withObservables(['comment'], ({ comment }) => ({
comment,
}))
const EnhancedComment = enhance(Comment)

And now you can render the whole Post:

const Post = ({ post, comments }) => (
<View>
<Text>{post.name}</Text>
<Text>Comments:</Text>
{comments.map(comment =>
<EnhancedComment key={comment.id} comment={comment} />
)}
</View>
)

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

The result is fully reactive! Whenever a post or comment is added, changed, or removed, the right components will automatically re-render on screen. Doesn't matter if a change occurred in a totally different part of the app, it all just works out of the box!

Example apps

A notes list (schema v2, migrations, create / pin / delete) ships as two apps, because React Native Windows 0.84 tracks RN 0.84.1 while Expo SDK 57 uses RN 0.86.2:

See each folder's README for run instructions.

Who uses WatermelonDB

Nozbe Teams
CAPMO
Mattermost
Rocket Chat
Steady
Aerobotics
Smash Appz
HaloGo
SportsRecruits
Chatable
Todorant
Blast Workout
Dayful
Learn The Words
ezypack

These apps were built on WatermelonDB. Does your company or app use NitromelonDB (or WatermelonDB)? Open a pull request and add your logo/icon with link here!

Contributing

We need you

NitromelonDB is an open-source project and it needs your help to thrive!

If there's a missing feature, a bug, or other improvement you'd like, we encourage you to contribute! Feel free to open an issue to get some guidance and see Contributing guide for details about project setup, testing, etc.

If you're just getting started, see good first issues that are easy to contribute to.

If you make or are considering making an app using NitromelonDB, please let us know!

Join the community on Discord.

Author and license

WatermelonDB was created by @Nozbe.

WatermelonDB's main author is Radek Pietruszewski (website𝕏 (Twitter)).

NitromelonDB is a maintained fork by Stas Doskalenko.

Original WatermelonDB contributors.

NitromelonDB is available under the MIT license. See the LICENSE file for more info.