as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

expo-sqlite

@amazon-devices/expo-sqlite gives your app access to a database that can be queried through a WebSQL-like API. The database is persisted across restarts of your app.

Installation

  1. Add the JavaScript library dependency in the package.json file.

    Copied to clipboard.

     dependencies: {
          ...
         "@amazon-devices/expo-sqlite": "~2.0.0",
         "@amazon-devices/keplerscript-turbomodule-api": "~1.0.0",
         "expo": "~50.0.0",
         ...
     }
    
  2. Reinstall dependencies using npm install command and rebuild your application with the kepler build command.

Examples

The example below provides a comprehensive example showing full database operations flow in a typical application.

Copied to clipboard.

import {openDatabase, SQLResultSet} from '@amazon-devices/expo-sqlite';
import React, {useEffect, useState} from 'react';
import {Button, StyleSheet, Text, View} from 'react-native';

let db = openDatabase('database.db');

export const App = () => {
  const [rows, setRows] = useState<any[][]>([]);

  const [dbClosed, setDbClosed] = useState(false);

  // create the database
  useEffect(() => {
    db.transaction((tx) => {
      tx.executeSql(
        'create table if not exists items (id integer primary key not null, done int, value text, floating double, int integer);',
      );
    });
  }, []);

  const handleSelectResult = (result: SQLResultSet) => {
    if (result.rows.length > 0) {
      const columnNames = Object.keys(result.rows._array[0]);
      const allRows = result.rows._array.map(Object.values);
      setRows([columnNames, ...allRows]);
    } else {
      setRows([]);
    }
  };

  // open the database
  const openDb = () => {
    db = openDatabase('database.db');

    db.transaction((tx) => {
      tx.executeSql(
        'create table if not exists items (id integer primary key not null, done int, value text, floating double, int integer);',
      );
    });

    setDbClosed(false);
  };

  // synchronously close the database
  const closeDbSync = () => {
    db.closeSync();
    setDbClosed(true);
  };

  // asynchronously close the database
  const closeDbAsync = async () => {
    await db.closeAsync();
    setDbClosed(true);
  };

  // perform insert operation synchronously
  const transactionSync = () => {
    db.transaction((tx) => {
      const done = Math.round(Math.random());
      const value = 'text-' + Date.now().toString().slice(-4);
      const float = Number((Math.random() * 10).toFixed(2));
      const int = Math.round(Math.random() * 1000);

      tx.executeSql(
        'insert into items (done, value, floating, int) values (?, ?, ?, ?)',
        [done, value, float, int],
        () => {},
      );
    });
  };

  // perform delete operation asynchronously
  const transactionAsync = async () => {
    await db.transactionAsync(async (tx) => {
      await tx.executeSqlAsync(
        'delete from items where id = (select max(id) from items)',
      );
    });
  };

  // perform select transaction synchronously
  const readTransactionSync = () => {
    db.readTransaction((tx) => {
      tx.executeSql('select * from items', [], (_, result) =>
        handleSelectResult(result),
      );
    });
  };

  // drop the database
  const deleteDb = () => {
    db.deleteAsync();
  };

  return (
    <View style={styles.container}>
      <View style={styles.sideColumn}>
        <Button title="open" onPress={openDb} disabled={!dbClosed} />
        <Button title="close sync" onPress={closeDbSync} disabled={dbClosed} />
        <Button
          title="close async"
          onPress={closeDbAsync}
          disabled={dbClosed}
        />
        <Button
          title="transaction sync (insert)"
          onPress={transactionSync}
          disabled={dbClosed}
        />
        <Button
          title="transaction async (delete)"
          onPress={transactionAsync}
          disabled={dbClosed}
        />
        <Button
          title="read transaction sync (select)"
          onPress={readTransactionSync}
          disabled={dbClosed}
        />
        <Button
          title="delete database"
          onPress={deleteDb}
          disabled={!dbClosed}
        />
      </View>
      <View style={styles.mainColumn}>
        <Text style={styles.label}>Database version: {db.version}</Text>
        <Text style={styles.label}>Database open: {String(!dbClosed)}</Text>
        <View style={styles.table}>
          {rows.map((row) => (
            <View style={styles.row}>
              {row.map((col) => (
                <View style={styles.cell}>
                  <Text style={styles.cellText}>{String(col)}</Text>
                </View>
              ))}
            </View>
          ))}
        </View>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  scrollView: {
    flex: 1,
  },
  container: {
    flex: 1,
    backgroundColor: 'white',
    flexDirection: 'row',
    padding: 20,
  },
  sideColumn: {
    flex: 1,
    flexDirection: 'column',
    padding: 10,
  },
  mainColumn: {
    flex: 2,
    flexDirection: 'column',
    padding: 10,
  },
  label: {
    color: 'black',
    fontSize: 32,
    flexDirection: 'column',
  },
  table: {
    alignItems: 'center',
    justifyContent: 'center',
  },
  row: {
    flexDirection: 'row',
    height: 40,
  },
  cell: {
    flex: 1,
    borderColor: 'black',
    borderWidth: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  cellText: {
    color: 'black',
    fontSize: 20,
  },
});

API reference

See the official Expo documentation.

Classes

Class Description
ExpoSQLTransactionAsync Internal data structure for the async transaction API
SQLError Class used for handling errors related to database operations
SQLiteDatabase The database returned by openDatabase()

SQLError properties

Property Description
code Error code
message Error message
CONSTRAINT_ERR This error code indicates a constraint violation
DATABASE_ERR This error code indicates a general error related to the database
SYNTAX_ERR This error code indicates a syntax error in the SQL statement
TOO_LARGE_ERR This error code indicates that the data being processed is too large to handle
UNKNOWN_ERR This error code indicates that and unknown or unexpected error has occured
VERSION_ERR This error code indicates a compatibility issue between the SQLite database version and the version expected by @amazon-devices/expo-sqlite

SQLiteDatabase properties

Property Description
close The method that can be used to close the database. WARNING: This method is deprecated and closeAsync() should be used instead
version The current version of the database

SQLiteDatabase methods

Method Description
closeAsync Closes the database
deleteAsync Delete the database file. The database has to be closed prior to deletion
exec Executes the SQL statement and returns a callback resolving with the result
execAsync Executes the SQL statement and returns a Promise resolving with the result
readTransaction Ensures the database is locked for reading only during the transaction
transaction Execute a database transaction
transactionAsync Creates a new transaction with Promise support

Methods

Method Description
openDatabase Open a database, creating it if it doesn't exist, and return a Database object. On disk, the database will be created under the app's documents directory, i.e. ${FileSystem.documentDirectory}/SQLite/${name}

Supported versions

Package Version Based On @amazon-devices/react-native-kepler version
2.0.x 11.8.0 2.0.x

Additional resources

For information on additional libraries, see Supported Third-Party Libraries and Services.


Last updated: Sep 30, 2025