npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@melon-db/db-sqlite-native

v0.1.0-alpha.0

Published

Melon JSI/TurboModule SQLite for React Native development builds

Readme

@melon-db/db-sqlite-native

Melon-owned SQLite native module for React Native development builds.

Not available in Expo Go. Use @melon-db/db-sqlite/expo for Expo Go and managed workflows.

Docs: Native SQLite architecture · Package guide

Platform support

| Platform | Native binding | Status | |----------|----------------|--------| | iOS (dev build) | Sync C++ JSI (global.melonSqliteJsi) + TurboModule fallback | Supported | | Android (dev build) | Sync C++ JSI (global.melonSqliteJsi) + TurboModule fallback | Supported | | Expo Go | N/A | Not available |

RN SQLite paths

| Path | Export | Binding | |------|--------|---------| | Expo Go (default) | @melon-db/db-sqlite/expo | expo-sqlite async | | Dev build (fast) | @melon-db/db-sqlite/rn + mode: 'auto' | Sync C++ JSI + dedicated DB queue | | Dev build (legacy) | @melon-db/db-sqlite/rn + mode: 'turbo' | Async TurboModule promises |

Limitations

  • Kotlin TurboModule exec() routes PRAGMA through rawQuery on the async fallback path only (C++ JSI uses sqlite3_exec).
  • BLOB / bytes fields are not round-tripped on the native path (returned as null).
  • Predicate-aware observeQuery ships in @melon-db/db-sqlite (shared adapter-core); native path uses the same invalidation.
  • Sync JSI calls block the JS thread until the native DB queue completes (intentional for throughput; keep queries bounded).

Requirements

  • React Native 0.76+ with New Architecture enabled
  • expo prebuild or bare React Native with autolinking

Codegen (TurboModule)

Spec: src/NativeMelonSQLite.ts. Regenerate artifacts after spec changes:

cd apps/playground-rn-dev

# iOS
node node_modules/react-native/scripts/generate-codegen-artifacts.js \
  -p ../../packages/melon-db-sqlite-native \
  -t ios \
  -o ../../packages/melon-db-sqlite-native/ios/generated \
  -s library

# Android (updates android/src/main/java/com/facebook/fbreact/specs/NativeMelonSQLiteSpec.java)
node node_modules/react-native/scripts/generate-codegen-artifacts.js \
  -p ../../packages/melon-db-sqlite-native \
  -t android \
  -o ../../packages/melon-db-sqlite-native/android/build \
  -s library

Then run expo prebuild --clean in apps/playground-rn-dev before native builds.

Gradle also generates android/build/generated/source/codegen/java when newArchEnabled=true during app builds.

Usage

Apps should not import this package directly. Use @melon-db/db-sqlite/rn:

import { Paths } from 'expo-file-system';
import { createJsiSqliteAdapter, isJsiSqliteAvailable } from '@melon-db/db-sqlite/rn';

if (!isJsiSqliteAvailable()) {
  throw new Error('Use a development build or switch to @melon-db/db-sqlite/expo');
}

const adapter = createJsiSqliteAdapter({
  filename: 'app.db',
  basePath: Paths.document.uri.replace(/^file:\/\//, ''),
  mode: 'auto', // prefers sync JSI when installed (iOS + Android)
});

Inspect binding mode:

import { getMelonSQLiteNativeMode } from '@melon-db/db-sqlite-native';
// 'jsi-sync' when C++ host object installed
// 'turbo' when forcing async path or host object absent
// null in Expo Go

Force async TurboModule for A/B comparison:

EXPO_PUBLIC_MELON_SQLITE=turbo bun run dev:rn:dev:start

Development build (playground-rn-dev)

# iOS
bun run dev:rn:dev
bun run dev:rn:dev:start

# Android
bun run dev:rn:dev:android
bun run dev:rn:dev:start

Expo Go demo: apps/playground-rn (bun run dev:rn).

Optional: EXPO_PUBLIC_MELON_SQLITE=expo in the dev app uses expo-sqlite instead of native.

Manual verification checklist

iOS

After bun run dev:rn:dev (or install:ios in apps/playground-rn-dev):

  1. App launches without native module errors.
  2. Runtime badge shows native jsi-sync (ios) (or native turbo (ios) when EXPO_PUBLIC_MELON_SQLITE=turbo).
  3. Seeded tasks appear (same as expo path).
  4. Add / complete tasks persist across restart.
  5. Sync demo works against bun run sync-server.
  6. Benchmarks: open Benchmarks from the task screen (__DEV__) or navigate to /benchmark; run jsi-sync + turbo @ 10k and share the JSON report.

Android

After expo prebuild --clean + bun run dev:rn:dev:android then bun run dev:rn:dev:start:

  1. App launches without native module errors.
  2. Runtime badge shows native jsi-sync (android) (or native turbo (android) when EXPO_PUBLIC_MELON_SQLITE=turbo).
  3. Seeded tasks appear.
  4. Add / complete tasks persist across restart.
  5. Sync demo works against bun run sync-server.

Architecture

  • Shared C++: cpp/MelonSQLiteHostObject.cpp + MelonSQLiteInstaller.cpp — sync JSI host object (openSync, queryAllSync, …) with a dedicated serial DB queue (GCD on iOS, worker thread on Android).
  • iOS install: MelonSQLiteTurboModule.mm calls installMelonSqliteJsi on first Turbo dispatch.
  • Android install: MelonSQLiteJni + NDK libmelon_sqlite.so installs via RuntimeExecutor on first Turbo call from MelonSQLiteModule.
  • Fallback: MelonSQLite TurboModule (MelonSQLiteSpec codegen) with async promises on both platforms.
  • JS: MelonSQLiteJsi.ts reads global.melonSqliteJsi; MelonSQLiteBridge.ts reports jsi-sync | turbo | bridge.

Observation (Phase 29): sqlite3_update_hook on JSI openSync schedules setObservationFlushCallback on the JS thread (coalesced). Pair with @melon-db/db-sqlite flushObservationQueue to process _melon_observation_events. Turbo/async native path does not install the hook in v1.

Author & license

Copyright (c) 2026 Nate Nichols. See LICENSE for the full MIT license text.