as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
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.1",
         "@amazon-devices/keplerscript-turbomodule-api": "~1.0.0",
         "expo": "~50.0.0",
         ...
     }
    
  2. Reinstall dependencies using the npm install command and rebuild your application with the vega build command.

Examples

This example is comprehensive, showing the 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 props

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

SQLiteDatabase props

Prop Description
close Closes 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 Deletes 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 Opens a database, creating it if it doesn't exist, and returns a Database object. On disk, the database is created under the app's documents directory ${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

Supported Third-Party Libraries and Services.


Last updated: Sep 30, 2025