Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 114 additions & 0 deletions .github/workflows/build-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: Build macOS

on:
push:
branches:
- main
paths:
- ".github/workflows/build-macos.yml"
- "example/macos/**"
- "example/src/**"
- "example/app.json"
- "example/index.js"
- "example/babel.config*.js"
- "packages/react-native-nitro-sqlite/**"
- "packages/react-native-nitro-sqlite-vec/**"
- "patches/**"
- "**/Podfile.lock"
- "**/Gemfile.lock"
- "**/bun.lock"
- "**/package.json"
- "**/react-native.config.js"
- "**/nitro.json"
pull_request:
paths:
- ".github/workflows/build-macos.yml"
- "example/macos/**"
- "example/src/**"
- "example/app.json"
- "example/index.js"
- "example/babel.config*.js"
- "packages/react-native-nitro-sqlite/**"
- "packages/react-native-nitro-sqlite-vec/**"
- "patches/**"
- "**/Podfile.lock"
- "**/Gemfile.lock"
- "**/bun.lock"
- "**/package.json"
- "**/react-native.config.js"
- "**/nitro.json"

env:
USE_CCACHE: 1

jobs:
build:
name: Build macOS Example App
runs-on: macos-26
steps:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2

- name: Install npm dependencies (bun)
run: bun install

- name: Install Ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
max-size: 1.5G
key: ${{ runner.os }}-ccache-example-macos
create-symlink: true
- name: Setup ccache behavior
run: |
{
echo "CCACHE_SLOPPINESS=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros"
echo "CCACHE_FILECLONE=true"
echo "CCACHE_DEPEND=true"
echo "CCACHE_INODECACHE=true"
} >> "$GITHUB_ENV"

- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.0
bundler-cache: true
working-directory: example

- name: Select Xcode 26.5
run: sudo xcode-select -s "/Applications/Xcode_26.5.app/Contents/Developer"

- name: Restore Pods cache
uses: actions/cache@v6
with:
path: example/macos/Pods
key: ${{ runner.os }}-pods-macos-${{ hashFiles('example/macos/Podfile.lock', 'example/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-macos-
- name: Clean generated macOS codegen
run: rm -rf example/macos/build/generated
- name: Install Pods
run: bun --cwd example pods:macos

- name: Restore DerivedData cache
uses: actions/cache@v6
with:
path: example/macos/build/DerivedData
key: ${{ runner.os }}-dd-macos-${{ hashFiles('example/macos/Podfile.lock', 'example/Gemfile.lock', '**/package.json', '**/bun.lock') }}-xcode26.5
restore-keys: |
${{ runner.os }}-dd-macos-${{ hashFiles('example/macos/Podfile.lock', 'example/Gemfile.lock', '**/package.json', '**/bun.lock') }}-xcode26.5

- name: Build App
working-directory: example/macos
run: |
set -o pipefail
xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build/DerivedData -UseModernBuildSystem=YES \
-workspace NitroSQLiteExample.xcworkspace \
-scheme NitroSQLiteExample-macOS \
-configuration Debug \
-destination 'platform=macOS,arch=arm64' \
-showBuildTimingSummary \
ONLY_ACTIVE_ARCH=YES \
build \
CODE_SIGNING_ALLOWED=NO | xcbeautify --renderer github-actions
5 changes: 3 additions & 2 deletions .github/workflows/test-harness-android.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Test Harness Android

on:
workflow_dispatch:
pull_request:
paths:
- ".github/workflows/test-harness-android.yml"
Expand All @@ -9,8 +10,8 @@ on:
- "example/tests/**"
- "example/rn-harness.config.mjs"
- "example/jest.config.js"
- "package/cpp/**"
- "package/android/**"
- "packages/react-native-nitro-sqlite/cpp/**"
- "packages/react-native-nitro-sqlite/android/**"
- "**/bun.lock"
- "**/react-native.config.js"
- "**/nitro.json"
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/test-harness-ios.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
name: Test Harness iOS

on:
workflow_dispatch:
pull_request:
paths:
- ".github/workflows/test-harness-ios.yml"
Expand All @@ -9,8 +10,8 @@ on:
- "example/tests/**"
- "example/rn-harness.config.mjs"
- "example/jest.config.js"
- "package/cpp/**"
- "package/ios/**"
- "packages/react-native-nitro-sqlite/cpp/**"
- "packages/react-native-nitro-sqlite/ios/**"
- "**/Podfile.lock"
- "**/*.podspec"
- "**/react-native.config.js"
Expand Down
65 changes: 65 additions & 0 deletions .github/workflows/test-macos.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Test macOS

on:
workflow_dispatch:
pull_request:
paths:
- ".github/workflows/test-macos.yml"
- "example/macos/**"
- "example/src/**"
- "example/tests/**"
- "example/app.json"
- "example/index.js"
- "example/babel.config*.js"
- "packages/react-native-nitro-sqlite/**"
- "packages/react-native-nitro-sqlite-vec/**"
- "patches/**"
- "**/Podfile.lock"
- "**/Gemfile.lock"
- "**/bun.lock"
- "**/package.json"
- "**/react-native.config.js"
- "**/nitro.json"

jobs:
test:
name: macOS Integration Tests
runs-on: macos-26

steps:
- uses: actions/checkout@v7
- uses: oven-sh/setup-bun@v2

- name: Install dependencies (bun)
run: bun install

- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.3.0
bundler-cache: true
working-directory: example

- name: Select Xcode 26.5
run: sudo xcode-select -s "/Applications/Xcode_26.5.app/Contents/Developer"

- name: Install Pods
run: bun --cwd example pods:macos

- name: Build debug app
working-directory: example/macos
run: |
set -euo pipefail
xcodebuild \
CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ \
-derivedDataPath build -UseModernBuildSystem=YES \
-workspace NitroSQLiteExample.xcworkspace \
-scheme NitroSQLiteExample-macOS \
-configuration Debug \
-destination 'platform=macOS,arch=arm64' \
build \
CODE_SIGNING_ALLOWED=NO

- name: Run macOS integration tests
working-directory: example/macos
run: bun run test
2 changes: 2 additions & 0 deletions .github/workflows/update-lockfiles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ jobs:
cd example
bundle install
bun pods
bun pods:macos
cd ..

git add bun.lock
git add example/ios/Podfile.lock
git add example/macos/Podfile.lock
git add example/Gemfile.lock

git config --global user.name 'dependabot[bot]'
Expand Down
68 changes: 62 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
> [!NOTE]
> Requires [Nitro modules](https://nitro.margelo.com/) and React Native `0.75` or later.

Nitro SQLite embeds SQLite and exposes a JSI API. Each operation is available in **sync** and **async** form; async runs off the JS thread to avoid blocking the UI.
Nitro SQLite embeds SQLite and exposes a JSI API on iOS, macOS, visionOS, and Android. Each operation is available in **sync** and **async** form; async runs off the JS thread to avoid blocking the UI.

---

Expand All @@ -44,6 +44,41 @@ npm install react-native-nitro-sqlite react-native-nitro-modules
npx pod-install
```

For a React Native macOS app, run CocoaPods from the `macos` directory:

```bash
cd macos && pod install
```

## Run the macOS example

From this repository's root, install dependencies and pods once, then launch the example in development mode:

```bash
bun install
bun --cwd example bundle-install
bun --cwd example pods:macos
bun --cwd example macos
```

The macOS app shares the iOS example's screens: **Unit Tests** runs the SQLite, TypeORM, and sqlite-vec suites; **SQL Console** runs ad-hoc queries against sample data; and **Benchmarks** measures inserts and reads.

To keep Metro in the current terminal, use:

```bash
# Terminal 1
bun --cwd example/macos start

# Terminal 2
bun --cwd example macos --no-packager
```

Build and launch the embedded production bundle with:

```bash
bun --cwd example macos --mode Release --no-packager
```

---

# API overview
Expand Down Expand Up @@ -76,6 +111,24 @@ const db = open({ name: 'myDb.sqlite' })

---

# SQLite thread safety on Apple platforms

Apple builds default to `NITRO_SQLITE_THREADSAFE=0` to preserve the existing iOS performance configuration. Set `NITRO_SQLITE_THREADSAFE=1` before installing Pods when one SQLite connection can be used from more than one native thread:

```bash
NITRO_SQLITE_THREADSAFE=1 npx pod-install
```

For React Native macOS, run the equivalent command from `macos/`:

```bash
NITRO_SQLITE_THREADSAFE=1 pod install
```

The repository's macOS example sets this automatically because Nitro async APIs run on worker threads.

---

# Basic usage

## Execute (sync and async)
Expand Down Expand Up @@ -178,7 +231,7 @@ const { rowsAffected, commands } = db.loadFile('/absolute/path/to/file.sql')

# Loading existing databases

Databases are created under the app documents directory (iOS) or files directory (Android). `location` is a directory path relative to that root, not an absolute file path. For example, `open({ name: 'myDb.sqlite', location: 'databases' })` opens `myDb.sqlite` under the `databases` directory. To use a database from another app-accessible location, copy or move it into this directory first. On iOS, files outside the app sandbox are inaccessible.
Databases are created under the app Documents directory (iOS and visionOS), Application Support directory (macOS), or files directory (Android). `location` is a directory path relative to that root, not an absolute file path. For example, `open({ name: 'myDb.sqlite', location: 'databases' })` opens `myDb.sqlite` under the `databases` directory. To use a database from another app-accessible location, copy or move it into this directory first. In sandboxed Apple apps, files outside the app sandbox are inaccessible.

Close a connection before deleting its database. A connection must not be used after `close()` or `delete()`.

Expand Down Expand Up @@ -216,10 +269,11 @@ Vector search is an opt-in companion package. It statically links sqlite-vec int
npm install react-native-nitro-sqlite-vec
```
2. Enable it for each native platform, then rebuild the app:
- **iOS:** run CocoaPods with `NITRO_SQLITE_VEC=1`, for example:
- **Apple platforms (iOS, macOS, visionOS):** run CocoaPods with `NITRO_SQLITE_VEC=1`, for example:
```bash
NITRO_SQLITE_VEC=1 npx pod-install
```
For React Native macOS, run `NITRO_SQLITE_VEC=1 pod install` from `macos/`.
- **Android:** add this to `android/gradle.properties`:
```properties
nitroSqliteVec=true
Expand Down Expand Up @@ -296,17 +350,19 @@ You can use this package as a TypeORM driver. Because of Metro and Node resoluti

# Configuration

## Use system SQLite on iOS
## Use system SQLite on Apple platforms

To use the system SQLite instead of the bundled one:

```bash
NITRO_SQLITE_USE_PHONE_VERSION=1 npx pod-install
```

For React Native macOS, run the command from `macos/` with `pod install` instead of `npx pod-install`.

## Compile-time options (e.g. FTS5, Geopoly)

**iOS** — in your app’s `ios/Podfile`, in a `post_install` block:
**Apple platforms** — in your app’s `Podfile`, in a `post_install` block:

```ruby
installer.pods_project.targets.each do |target|
Expand All @@ -325,7 +381,7 @@ end
nitroSqliteFlags="-DSQLITE_ENABLE_FTS5=1"
```

## App groups (iOS)
## App groups (Apple platforms)

To put the database in an app group (e.g. for extensions), set `RNNitroSQLite_AppGroup` in your `Info.plist` to the app group ID and add the App Groups capability in Xcode.

Expand Down
Loading