Registry / database / expo-sqlite

expo-sqlite

JSON →
library55.0.15jsnpmunverified

expo-sqlite provides a robust interface for local SQLite database persistence within Expo and React Native applications. As of version 55.0.15, it integrates seamlessly with Expo SDK 55. New Expo SDK versions, and consequently updates to expo-sqlite, are typically released three times per year, aligning with the React Native release cadence. This package offers a modern promise-based API for core database operations, including creating tables, inserting, querying, and managing transactions. Its primary differentiator is the streamlined integration into the Expo ecosystem, abstracting away complex native module setup for React Native developers. It is a fundamental tool for building offline-first features and for efficient, structured local data storage, distinguishing itself from simpler key-value stores like `AsyncStorage` when complex queries or relationships are required.

npm install expo-sqlite
INSTALL
IMPORT
SIG · EXPO-SQLITE
E
expo-sqlite
databasejavascriptv55.0.15
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

openDatabase
import { openDatabase } from 'expo-sqlite';
import * as SQLite from 'expo-sqlite'; const db = SQLite.openDatabase('name.db');
Since Expo SDK 49, `openDatabase` is a direct named export. The previous pattern of `SQLite.openDatabase` from a namespace import is deprecated and will result in errors.
openDatabaseAsync
import { openDatabaseAsync } from 'expo-sqlite';
const { openDatabaseAsync } = require('expo-sqlite');
Introduced in Expo SDK 49, `openDatabaseAsync` provides a modern promise-based API. Prefer this over the callback-based `openDatabase` for new code. CommonJS `require` is not supported for `expo-sqlite` in recent SDK versions.
SQLiteDatabase
import { SQLiteDatabase } from 'expo-sqlite';
This type definition is crucial for TypeScript users to correctly type database instances returned by `openDatabase` or `openDatabaseAsync`.

This quickstart demonstrates how to open a SQLite database, create a table, insert new notes, and fetch all existing notes, displaying them in a React Native component. It uses the modern promise-based API and proper error handling within transactions.

import { openDatabase, SQLiteDatabase } from 'expo-sqlite'; import React, { useState, useEffect } from 'react'; import { View, Text, Button, Alert, StyleSheet } from 'react-native'; const db: SQLiteDatabase = openDatabase('my_app_data.db'); export default function App() { const [items, setItems] = useState<string[]>([]); useEffect(() => { db.transaction(tx => { tx.executeSql( 'CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY NOT NULL, text TEXT NOT NULL);', [], () => console.log('Table "notes" created or already exists.'), (_, error) => { console.error('Error creating table:', error); return true; // Indicate transaction should rollback on error } ); }, (error) => console.error('Transaction error:', error), () => { console.log('Database initialization complete.'); fetchNotes(); }); }, []); const addNote = async () => { const newNote = `Note ${Date.now()}`; db.transaction(tx => { tx.executeSql( 'INSERT INTO notes (text) VALUES (?);', [newNote], () => { Alert.alert('Success', `Added "${newNote}"`); fetchNotes(); }, (_, error) => { console.error('Error adding note:', error); return true; } ); }); }; const fetchNotes = () => { db.transaction(tx => { tx.executeSql( 'SELECT * FROM notes;', [], (_, { rows }) => { setItems(rows._array.map((item: any) => item.text)); }, (_, error) => { console.error('Error fetching notes:', error); return true; } ); }); }; return ( <View style={styles.container}> <Text style={styles.title}>SQLite Notes</Text> <Button title="Add New Note" onPress={addNote} /> <Button title="Refresh Notes" onPress={fetchNotes} /> <View style={styles.notesContainer}> {items.length === 0 ? <Text>No notes yet.</Text> : items.map((item, index) => ( <Text key={index} style={styles.noteItem}>- {item}</Text> ))} </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingTop: 50 }, title: { fontSize: 24, marginBottom: 20 }, notesContainer: { marginTop: 20 }, noteItem: { marginVertical: 5 } });
Debug
Known issues
breakingStarting with Expo SDK 49, the primary API for opening a database changed. You must now import `openDatabase` (or `openDatabaseAsync`/`openDatabaseSync`) directly as a named export. The legacy `import * as SQLite` and then calling `SQLite.openDatabase` is no longer supported and will cause runtime errors.
fix
Update your import statements from `import * as SQLite from 'expo-sqlite'; const db = SQLite.openDatabase(...)` to `import { openDatabase } from 'expo-sqlite'; const db = openDatabase(...)` for callback-based, or `import { openDatabaseAsync } from 'expo-sqlite'; const db = await openDatabaseAsync(...)` for promise-based.
affects: >=49.0.0
gotchaAll SQLite operations (e.g., `executeSql`, transactions) are asynchronous. Failing to properly handle promises or callbacks can lead to race conditions, unexpected data states, or errors where operations complete out of order.
fix
Always use `async/await` with promise-based APIs (`openDatabaseAsync`, `runAsync`, `getAllAsync`) or ensure all logic dependent on a database operation's completion is placed within the success callback of the transaction or `executeSql` call.
affects: >=1.0.0
gotcha`expo-sqlite` databases are sandboxed to the application. Database files cannot be directly accessed by other apps or outside the application's secure storage area, and the database will be deleted if the application is uninstalled.
fix
If you need to backup or migrate data, implement application-level export/import functionality using other Expo modules like `expo-file-system` to read/write database content to user-accessible directories or cloud storage, or use `serializeAsync` / `deserializeDatabaseAsync` APIs.
affects: >=1.0.0
gotchaAttempting to use `require('expo-sqlite')` will result in an `ERR_REQUIRE_ESM` error in modern Expo SDKs. `expo-sqlite` is published as an ES Module (ESM), and direct CommonJS `require()` is not supported.
fix
Always use ES module import syntax: `import { openDatabase } from 'expo-sqlite';` or `import { openDatabaseAsync } from 'expo-sqlite';`. Ensure your project's Metro/Babel configuration correctly handles ESM.
affects: >=49.0.0
Errors
Common errors & fixes
Error: no such table: MyTable
The SQL query references a table name that does not exist or is misspelled in the database schema.
fix
Verify that the table was correctly created before attempting to query or modify it. Check for typos in the table name in both your `CREATE TABLE` and subsequent `SELECT`/`INSERT`/`UPDATE` statements.
TypeError: _expo_sqlite__WEBPACK_IMPORTED_MODULE_0__.openDatabase is not a function
You are likely using an older import pattern (`import * as SQLite from 'expo-sqlite'; SQLite.openDatabase`) with a newer Expo SDK version that expects direct named exports.
fix
Change your import to `import { openDatabase } from 'expo-sqlite';` for the callback API or `import { openDatabaseAsync } from 'expo-sqlite';` for the promise API, and use `openDatabase(...)` or `await openDatabaseAsync(...)` directly.
Error: Database is locked
Concurrent write operations are attempting to access the database simultaneously without proper transaction management, or a previous transaction was not properly closed.
fix
Ensure that all database modifications are wrapped within a single transaction. Avoid opening multiple simultaneous database connections for writes. If using promise-based APIs, ensure `await` is used correctly to prevent concurrent access.
Error [ERR_REQUIRE_ESM]: require() of ES Module C:\path\to\node_modules\expo-sqlite\build\index.js not supported.
Your project is attempting to import `expo-sqlite` using CommonJS `require()` syntax, but `expo-sqlite` is an ES Module (ESM) in recent Expo SDKs.
fix
Migrate all `require('expo-sqlite')` statements to `import { openDatabase } from 'expo-sqlite';` (or `openDatabaseAsync`). Ensure your build environment (e.g., Metro, Babel) is configured to handle ESM properly.
Upgrade
Version history
55.0.15latest on npm
Audit
Dependencies
exporequiredCore Expo runtime environment and build tooling.
reactrequiredReact's component model and hooks for state management in React Native applications.
react-nativerequiredThe underlying framework for building native mobile applications.
Agent activity
8 hits · last 30 days
node
8
Resources
expo-sqlite — npm install expo-sqlite · libregistry