Skip to main content

⚙️ Supastash Configuration

The configureSupastash() function sets up Supastash and must be called once at app startup—typically in your lib/supastash.ts file or before rendering any routes.

import { configureSupastash, defineLocalSchema } from "supastash";
import { supabase } from "./supabase";
import { openDatabaseAsync } from "expo-sqlite";

configureSupastash({
dbName: "supastash_db",
supabaseClient: supabase,
sqliteClient: { openDatabaseAsync },
sqliteClientType: "expo",
debugMode: true,
onSchemaInit: async () => {
defineLocalSchema("users", {
id: "TEXT PRIMARY KEY",
name: "TEXT",
email: "TEXT",
created_at: "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",
updated_at: "TIMESTAMP DEFAULT CURRENT_TIMESTAMP",
});
},
});

🧱 Configuration Options

OptionTypeRequiredDefaultDescription
dbNamestring✅ Yes"supastash_db"Name of the local SQLite database.
supabaseClientSupabaseClient✅ YesnullA configured instance of your Supabase client.
sqliteClientobject✅ YesnullThe SQLite adapter instance. Must match the selected sqliteClientType.
sqliteClientType"expo" | "rn-storage" | "rn-nitro"✅ YesnullSpecifies which SQLite engine you're using.
onSchemaInit() => Promise<void> | void❌ NoundefinedOptional callback to define local tables using defineLocalSchema(). Called once after DB creation.
debugModeboolean❌ NofalseLogs internal sync and DB activity for debugging.
listenersnumber❌ No250Maximum number of Realtime listeners to attach.
excludeTables{ pull?: string[], push?: string[] }❌ No{ pull: [], push: [] }Prevents specific tables from being synced (pull/push).
pollingInterval{ pull?: number, push?: number }❌ No{ pull: 30000, push: 30000 }Interval (ms) for polling Supabase for changes.
syncEngine{ push?: boolean, pull?: boolean, useFiltersFromStore?: boolean }❌ No{ push: true, pull: false, useFiltersFromStore: true }Controls sync behavior. See below.

🔁 syncEngine Options

push (default: true)

  • Automatically pushes local changes to Supabase.
  • If disabled, changes are stored locally but not uploaded.

pull (default: false)

  • Enables automatic background pull sync from Supabase to SQLite.
  • Only enable if your tables are protected with RLS or you have safe public filters in place.

useFiltersFromStore (default: true)

  • When enabled, pull sync applies filters stored during hook usage (e.g., from useSupatashData()).
  • This ensures only relevant data is pulled even when pull is globally enabled.

💡 Notes

  • configureSupastash() must be called before any hook or sync action.
  • Internally sets up the entire sync and storage context.
  • If you're calling this more than once, or across modules, ensure sqliteClientType and sqliteClient are consistent.

🧠 SQLite Client Types

Choose one based on your app’s architecture:

TypeDescription
"expo"Uses expo-sqlite. Simple and stable for most use cases.
"rn-nitro"Uses react-native-nitro-sqlite. Great for performance in large apps.
"rn-storage"Uses react-native-sqlite-storage. Legacy option, but widely supported.

Each type expects a different shape for sqliteClient. For example:

For expo

sqliteClientType: "expo",
sqliteClient: { openDatabaseAsync }

For nitro

sqliteClientType: "rn-nitro",
sqliteClient: { open }

For rn-storage

sqliteClientType: "rn-storage",
sqliteClient: { openDatabase }

🔐 Example With RLS Pull Sync Enabled

Enable pull: true only after securing your tables:

syncEngine: {
push: true,
pull: true,
}

Make sure to provide filtered hooks like:

useSupatashData("orders", {
filter: { column: "user_id", operator: "eq", value: userId },
shouldFetch: !!userId,
});

🧼 Resetting or Reconfiguring

The config can only be set once per session. To reset:

🔗 What’s Next?