margelo / margelo/react-native-nitro-sqlite
feat(expo): add an official config plugin for CNG and EAS Build
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 565
- Forks
- 53
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 18
Description
Summary
react-native-nitro-sqlite works in Expo development builds through autolinking, but its optional native build configuration is currently manual:
- iOS FTS5/other SQLite flags require a consumer
Podfilepost_installmutation. - Android flags require
android/gradle.properties(nitroSqliteFlags). - sqlite-vec uses the separate
NITRO_SQLITE_VEC=1/nitroSqliteVec=trueswitches after the companion package is installed. - iOS App Group database storage requires both
RNNitroSQLite_AppGroupinInfo.plistand the Xcode App Groups entitlement. - iOS system SQLite currently requires setting
NITRO_SQLITE_USE_PHONE_VERSION=1while installing pods.
That prevents a complete managed Expo / EAS Build / Continuous Native Generation setup: generated ios and android projects should not need hand-edited Podfiles, Gradle properties, Info.plists, or entitlements.
Expo recommends library-owned config plugins for native setup. A built-in plugin would make the existing supported native capabilities reproducible across local expo prebuild, expo run:*, and EAS Build.
Proposed package surface
Ship a compiled plugin with the core package:
// app.config.ts
export default {
expo: {
plugins: [
[
'react-native-nitro-sqlite',
{
fts5: true,
sqliteVec: false,
ios: {
appGroup: 'group.com.example.shared',
useSystemSqlite: false,
},
sqliteFlags: {
ios: ['SQLITE_ENABLE_GEOPOLY=1'],
android: ['-DSQLITE_ENABLE_GEOPOLY=1'],
},
},
],
],
},
}
Suggested API principles:
fts5?: booleandefaults tofalse; the plugin mapstruetoSQLITE_ENABLE_FTS5=1on both platforms. Keep it opt-in: FTS adds binary size/attack surface and is not required by every database consumer.sqliteFlags?: { ios?: string[]; android?: string[] }is additive/advanced. Validate each entry (KEY=VALUEon iOS,-DKEY=VALUEon Android), de-duplicate it, and reject flags that contradict the library's fixed safety/ABI settings. Do not add a broad arbitrary-string escape hatch that can silently break a build.ios?: { appGroup?: string; useSystemSqlite?: boolean }.appGroupwrites the existingRNNitroSQLite_AppGroupInfo.plist key and adds the exact identifier to the app target'scom.apple.security.application-groupsentitlement. It must preserve existing groups and fail clearly for malformed identifiers.useSystemSqliteshould reproduce the current pod-install setting for the library pod only.sqliteVec?: booleanbelongs to the companionreact-native-nitro-sqlite-vecpackage's plugin, not core. The core plugin may detect that the companion is installed and emit a targeted error / documentation link whensqliteVec: trueis passed, but should not import or hard-depend on it. The companion plugin can delegate shared flag helpers from core and configure both native switches only when the companion package is resolvable.
The first version should intentionally not expose the podspec's performance_mode: it is hard-coded today and its threading semantics need a separate API/safety decision. Likewise, useSystemSqlite should be explicit and documented as a platform-version/feature trade-off, not enabled implicitly.
Native modifications
iOS
- Use
withInfoPlistforRNNitroSQLite_AppGroup. - Use
withEntitlementsPlist(and, only if necessary,withXcodeProject) to merge the App Groups entitlement without removing app-owned entries. - Use the narrowest safe CocoaPods/Podfile-properties mechanism to apply library-scoped C/C++ preprocessor definitions and
NITRO_SQLITE_USE_PHONE_VERSION=1. Do not mutate unrelated targets or overwrite an app'spost_installhook.
Android
- Use
withGradlePropertiesto mergenitroSqliteFlagsinto the existing property without duplicate-Ddefinitions. - The companion plugin owns
nitroSqliteVec=true; it must verify the companion package is installed before enabling it. - No manifest change is expected for core SQLite/FTS/vector configuration.
Acceptance criteria
- The package exposes
app.plugin.jsand typed plugin options, with the plugin build included in published artifacts and compatible with app.config.js/ts/json configuration. - Re-running prebuild is idempotent: no duplicate flags, plist keys, app groups, Podfile edits, or Gradle properties.
- Existing manual configuration remains supported and composes without overrides; conflicts produce actionable errors.
fts5: trueproduces a build whereSELECT sqlite_compileoption_used('ENABLE_FTS5')is true on iOS and Android, and FTS table creation succeeds.- The companion package's plugin reliably enables sqlite-vec on iOS and Android; a build without it leaves the base package vector-free.
ios.appGroupproduces both the Info.plist value consumed by NitroSQLite and the matching app-target entitlement, while preserving pre-existing entitlements.ios.useSystemSqliteproduces a build linked with system SQLite and the docs state which bundled capabilities may differ.- Unit tests cover option validation, platform transformations, merging and idempotency. An Expo example/test fixture runs clean prebuild for iOS and Android and checks generated plist/entitlements/Gradle outputs. CI should run that CNG fixture against the supported Expo SDK range.
- README documents the declarative setup plus the legacy manual setup, explicit rebuild requirement, and EAS Build behavior.
Prior art / context
- Current manual configuration: README “Configuration” section; core podspec and Android Gradle script already read the relevant switches.
- Existing Expo issues appear to be historical build failures (#2, #12, #65, #85, #100) rather than a CNG config-plugin implementation. App Group support was added in #8, but it still requires manual native configuration.
- Expo documentation: https://docs.expo.dev/config-plugins/development-for-libraries/ and https://docs.expo.dev/workflow/continuous-native-generation/
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the README Configuration section, the core podspec, and the Android Gradle script to trace the existing switches and manual setup. Then review the Expo config-plugin and CNG documentation before defining the plugin surface and fixture coverage. Done means published typed options, idempotent native transformations, validation and merge tests, a clean iOS/Android prebuild fixture, and updated README guidance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react-native, typescript
- Domain
- build-system, mobile
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100