TypeORM
Use Nitro SQLite as the database driver for TypeORM's React Native DataSource.
TypeORM maps application entities to database tables and builds SQL for operations on those entities. Its DataSource needs a driver to open SQLite and run the generated queries in a React Native app.
Nitro SQLite exports typeORMDriver for TypeORM's react-native database type. TypeORM calls the driver, which opens a regular Nitro SQLite connection and uses its async query method. Use open() directly when you do not need TypeORM.
Configure module resolution
Install typeorm, react-native-nitro-sqlite, and babel-plugin-module-resolver in the app. The repository's working example uses TypeORM 0.3.27 and makes two resolution changes:
-
Expose
./package.jsonin TypeORM'sexportsmap. The repository keeps this as a persistent package patch:"exports": { + "./package.json": "./package.json", ".": { -
Alias the SQLite storage package name that TypeORM imports to Nitro SQLite in
babel.config.js:module.exports = { presets: ['module:@react-native/babel-preset'], plugins: [ [ 'module-resolver', { alias: { 'react-native-sqlite-storage': 'react-native-nitro-sqlite', }, }, ], ], }
Merge this plugin into your existing Babel configuration rather than replacing the rest of its plugins.
Create a DataSource
import { DataSource, EntitySchema } from 'typeorm'
import { typeORMDriver } from 'react-native-nitro-sqlite'
type Note = { id: number; title: string }
const NoteEntity = new EntitySchema<Note>({
name: 'Note',
columns: {
id: { type: Number, primary: true, generated: true },
title: { type: String },
},
})
const dataSource = new DataSource({
type: 'react-native',
database: 'notes.sqlite',
location: '.',
driver: typeORMDriver,
entities: [NoteEntity],
synchronize: true,
})
await dataSource.initialize()
const notes = dataSource.getRepository(NoteEntity)
await notes.save({ title: 'First note' })
const saved = await notes.find()
await dataSource.destroy()This small example uses synchronize: true to create the table. Choose your application's schema management before shipping. database becomes the connection's name; location is a directory relative to the platform database root.
Driver export
typeORMDriver has one public method, openDatabase(options, ok, fail). The following reference types describe its inferred shape. TypeORMAdapterConnection and TypeORMDriver below are names used only in this page; the package does not export them.
import type {
QueryResult,
QueryResultRow,
SQLiteQueryParams,
Transaction,
} from 'react-native-nitro-sqlite'
type TypeORMAdapterConnection = {
executeSql<Row extends QueryResultRow = never>(
sql: string,
params: SQLiteQueryParams | undefined,
okExecute: (result: QueryResult<Row>) => void,
failExecute: (message: string) => void,
): Promise<void>
transaction(fn: (tx: Transaction) => Promise<void>): Promise<void>
close(okClose: () => void, failClose: (error: unknown) => void): void
attach(
dbNameToAttach: string,
alias: string,
location: string | undefined,
callback: () => void,
): void
detach(alias: string, callback: () => void): void
}
type TypeORMDriver = {
openDatabase(
options: { name: string; location?: string },
ok: (connection: TypeORMAdapterConnection) => void,
fail: (message: string) => void,
): TypeORMAdapterConnection | null
}openDatabase() returns the adapter connection after calling ok, or null after invoking fail when opening fails. executeSql() runs db.executeAsync() and then invokes one result callback. close(), attach(), and detach() are synchronous; their success callbacks run after the operation succeeds. TypeORM normally handles this contract for you.
The failure callbacks for openDatabase and executeSql are typed to receive a string, but the adapter casts caught errors to that type without converting them at runtime. Handle an Error value as well if you call these callbacks directly. This adapter is for TypeORM's callback interface, not a connection object for direct SQL calls. For those, see the API reference.